I am showing the value of the timer.php through AJAX in index.php . However I am concern about the performance of this, if it is a server killer if there are 30 people online, and things like this. Do you suggest me some edits?
Thank you.
index.php
<script language='JavaScript'>
setInterval( 'SANAjax();', 1000 );
$(function() {
SANAjax = function(){
$('#dataDisplay').load('timer.php');
}
});
</script>
<div id="dataDisplay"></div>
timer.php
function time_difference($endtime){
$days= (date("j",$endtime)-1);
$hours =date("G",$endtime);
$mins =date("i",$endtime);
$secs =date("s",$endtime);
$diff="'day': ".$days.",'hour': ".$hours.",'min': ".$mins.",'sec': ".$secs;
return $diff;
}
$future_time = mktime(0, 0, 0, 9, 19, 2011);
$now_time = strtotime("+2 hours");
$end_time = $future_time - $now_time;
$difference = time_difference($end_time);
if ($future_time <= $now_time ) { echo "Date reached"; } else { echo $difference; };
?>
Depends on your server specs and number of clients, this could quickly become a server-killer.
The multiple calls to a file every second will quickly put a lot of load for nothing though, so best practice calls for using a javascript timer countdown. I particularly like this one: http://stuntsnippets.com/javascript-countdown/
And for the jQuery implementation:
<script type="text/javascript">
var myDate = new Date(); //Retrieve actual date
myDate.setTime(this.getTime() + (3600 * 2)); //Add two hours
$(document).ready(function() {
$("#time").countdown({
date: myDate.toGMTString(),
onComplete: function( event ){
$(this).html("completed");
},
leadingZero: true
});
});
</script>
<p id="time" class="time"></p>
This should be enough, no more need for PHP calls and the client does everything.
By setting a setInterval for every second, you are basically saying that for 30 clients, you will be getting roughly 30 txn per second to your php server. Its hard to say its a performance killer outside of just saying you will have to handle 30tps for this simple call. I would first quesiton why you are doing this with a server side script. You could just as easily give the html file a datetime when the page loads and do the countdown with just javascript in the browser.
I use jQuery Countdown http://keith-wood.name/countdown.html to put a timer on my pages to let the user know when they are going to be logged out of the system due to inactivity.
You can bind a function to the counter expiring event.
http://code.google.com/p/jquery-countdown/ ...Simple example
http://keith-wood.name/countdown.html ...shows off all the bells and whistles...
It can be as simple as the first one or as detailed as the second!
-=Bryan
Related
We are using the following countdown function on our bidding site.
setInterval(function(){
$(".countdown").each(function(){
var seconds = $(this).data('seconds');
if(seconds > 0) {
second = seconds - 1;
$(this).data('seconds', second)
var date = new Date(null);
date.setSeconds(second);
$(this).html(date.toISOString().substr(11, 8))
}
else
{
$(this).html("Finished");
alert('finished');
}
});
}, 1000);
we pass the number of seconds where we want the counter to appear (sometimes more than once on our page:
echo "<div id=\"".$auctionid."\" class=\"countdown\" data-seconds=\"".$diff."\"></div>";
So far it should be clear an it works. Now we have a situation where when someone bids somewhere on the site - the time left for auction is prolonged for 15 seconds, which is written to mysql.
$diff variable is calculated from mysql end time, and it's passed to jQuery on page load.
The question is how to check the mysql time for that auction and sync it in jQuery counter? We had the idea to maybe check every 5 seconds and after it reaches zero to make sure it's over? Any suggestions?
It should look nice to the user.
EDIT:
This is what we have so far:
$(".countdown").each(function() {
var countdown = $(this);
var auctionid = $(this).attr('id');
var interval = setInterval(function() {
var seconds = countdown.data("seconds");
if( seconds > 0 ) {
var second = --seconds;
var date = new Date(null);
date.setSeconds(second);
countdown.data("seconds", second).html(date.toISOString().substr(11, 8))
} else {
// countdown.html("Finished <img src=\"loading.gif\" class=\"tempload\">");
startUpdateingTimeFromDatabase(auctionid);
countdown.html("Finished");
clearInterval(interval);
}
}, 1000);
});
function startUpdateingTimeFromDatabase(auctionid) {
$.getJSON("timer.php?auctionid="+auctionid, function(response) {
// console.log(response.seconds);
$(".countdown#"+auctionid).data("seconds", response.seconds);
if( response.seconds > 0 ) {
// setTimeout(startUpdateingTimeFromDatabase(auctionid), 1000);
} else {
}
});
}
This simply isn't doing what we need it to do. We need to update the seconds (query startUpdateingTimeFromDatabase) every time it reaches zero. Now I think there are two approaches. First is simply return seconds via startUpdateingTimeFromDatabase function and then do everything in the main function, second is update the div via startUpdateingTimeFromDatabase. I think first will be better but I simply can't find a way to do it properly.
Any help is appreciated. Thanks.
You store the seconds left in the elements data. So why not fetch the remaining time maybe via ajax and just pass the new seconds to the elements? Within the next interval run all times will be updated.
Something like this:
$.get("yourGetRemainingTimeScript.php", {auctionId: 1}, function(response) {
$(".countdown").data("seconds", response.seconds);
});
How you check and get the remaining time is up to you. You can set the time for all everywhere again.
$(".countdown").data("seconds", 1337);
Another hint from my side: don't loop all elements with each in the setInterval. Create the intervals inside the loop once. Then your script doesn't need to search every second again over and over for the elements.
And clear the interval when it's finished.
$(".countdown").each(function() {
var countdown = $(this);
var interval = setInterval(function() {
// do your stuff ...
// when finished stop the interval
if( finished ) {
clearInterval(interval);
}
}, 1000);
});
Full working example.
i'm using jquery countdown with php. i have given an end date which is going to the countdown. my problem is lets suppose 1 hour left is showing in countdown but when a user change its system time the countdown changes. like if a user back his time 1 hour then the counter will display the 2 hours left. is there any way to get the server time for more accurate time not the user system time. please help.
how can i get server time not user system time?
below is my jquery code
if($(pluginsArray[6]).length){
$(pluginsArray[6]).each(function(){
var $this = $(this),
dateObj = $this.data();
var finalDate = new Date(dateObj.year, dateObj.month, dateObj.day, dateObj.hours, dateObj.minutes);
$this.countdown({
timezone: +4,
until : finalDate,
expiryText: '<div class="over">Closed.</div>',
onExpiry : function(){
setTimeout(function( ) { location.reload(); }, 5000);
},
format :'DHMS',
layout : '<b>{dn}</b> <span class="fs_medium d_inline_b m_right_5">days</span> <b>{hn}</b> <span class="fs_medium d_inline_b m_right_5">hrs</span> <b>{mn}</b> <span class="fs_medium d_inline_b m_right_5">min</span> <b>{sn}</b> <span class="fs_medium">sec</span>'
});
});
}
and here is what i did in php
<div class="countdown color_redc d_inline_m fs_large second_font lh_small f_xs_20" style="font-size:26px;" data-year="<?= $aDate[0] ?>" data-month="<?= ($aDate[1] - 1) ?>" data-day="<?= $aDate[2] ?>" data-hours="<?= $aDate[3] ?>" data-minutes="<?= $aDate[4] ?>"></div>
Solution without PHP
What you can do, without coding any server side is using a public API to get current time.
Found a similar topic on StackoverFlow : Free Rest API to get current time as string (timezone irrelevant)
TimezoneDb provides a free API: http://timezonedb.com/api
GenoNames also has a RESTful API available to get the current time for
a given location: http://www.geonames.org/export/ws-overview.html.
You can use Greenwich, UK if you'd like GMT.
GenoNames looks to be US only, TimezoneDb works you just need to register for a free public key.
Few people recommend timeapi.org but looks like they do not accept CROSS-DOMAIN request in Ajax, and the exemple they provide is no longer available.
Solution with PHP and jQuery Countdown configuration
Also you can ask jQuery CountDown to synchronyze with your server using serverSync option
$(selector).countdown({
until:liftoffTime, serverSync: serverTime});
function serverTime() {
var time = null;
$.ajax({url: 'http://myserver.com/serverTime.php',
async: false, dataType: 'text',
success: function(text) {
time = new Date(text);
}, error: function(http, message, exc) {
time = new Date();
}});
return time;
}
PHP file : serverTime.php
<?php
$now = new DateTime();
echo $now->format("M j, Y H:i:s O")."\n";
?>
BUT
Keep in mind your user will always be able to change your code and fake it ... so if you need to implement some security this is not enough and you will need to code some backend stuff.
I'm trying to display the current timestamp and refresh every second, doing this with php is too slow and has to reload the page and I know javascript doesn't, I just don't know how to, any help?
<?php
$time = time() + 3600 * 15;
echo $time;
?>
<meta http-equiv="refresh" content="0.5;time.php" />
Thanks in advance.
JavaScript can call up a timestamp based on your local time. Use setInterval to loop and update the timestamp given by Date.now().
setInterval(function() {
document.getElementById("timestamp").innerHTML = Date.now();
}, 16);
See jsFiddle.
So here's what I'm trying to do - I have the following code:
<div id="on">
<p>We are: <span class="onair">ON AIR</span></p>
</div>
<div id="off">
<p>We are: <span class="offair">OFF AIR</span></p>
</div>
And what I'd like to do is "show" the "on" div on Tuesday's from 3pm to 4pm (server time), while simultaneously hiding the "off" div - and then switch that around for every other date/time.
?
If you use PHP you can do logic statements on the server-side to render the exact information you need instead of calculating it later on the client side.
(Client side solutions work too if you dont care about where the time is coming from)
(1) You can have the server render javascript for you that you can use in a script
//if you want the server's time you can do this:
<?php $timestamp = time(); ?>
//render variables in javascript instead of html
<?php
echo <<<EOD
<script>
var timestamp = ${timestamp}
//then later in your javascript process the timestamp logic to update the dom
</script>
EOD;
?>
(2) You can also have the server render a className in the body tag based on whether or not a condition is true or false. (This is my preferred method usually)
//onAirClass( min, max, timestamp ) returns className
//this function returns onair or offair class if the timestamp is in range
function onAirClass( timeMin, timeMax, timestamp ){
if( timestamp >= timeMin && timestamp <= timeMax ){
return 'onair';
}
return 'offair'
}
//using onAirClass( min, max, timestamp )
<?php $bodyClass = $bodyClass . ' ' . onAirClass( $timestamp ); ?>
<?php echo "<body class='${bodyClass}'>"; ?>
then in your styles you can have the elements you want to hide or show based on class inheritance from the body tag.
Check out the PHP time function to create new time strings, and do time calculations for your onAirClass() function
How to check the time between a given time range
UPDATED
Corrected PHP syntax errors
#maerics solution is OK, depending on what you want to do, just don't EVER do anything like this:
var timestamp = $('#server-timestamp').text();
Ultimately, there are many ways to do the same thing, but some things are more 'right' than others.
There are reasons to do some calculations on the client side vs the server side, and vice versa. As a newbie developer, just make sure that whatever method you use:
is simple
is efficient (doesnt do anything unnecessary or redundant)
falls in line with best practices
Actually this can be accomplished using just JavaScript without any server-side code, by using your timezone offset.
Here's a function you can use:
var onAir = function (day, start, end, timezone) {
var local, utc, show, days, onAir, startValues, endValues, startTime, endTime, startMinutes, endMinutes, showMinutes;
// by default, we are not on air
onAir = false;
// map day numbers to indexes
days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Firday', 'Saturday'];
// convert start/end times to date objects
startValues = start.split(':');
endValues = end.split(':');
startTime = new Date();
endTime = new Date();
startTime.setHours(startValues[0], startValues[1]);
endTime.setHours(endValues[0], endValues[1]);
// add the hours minutes together to get total minutes
startMinutes = (startTime.getHours() * 60) + startTime.getMinutes();
endMinutes = (endTime.getHours() * 60) + endTime.getMinutes();
// get the current local time
local = new Date();
// get the current time in the show's timezone
utc = local.getTime() + (local.getTimezoneOffset() * 60000);
show = new Date(utc + (3600000*timezone));
// convert the show hours + minutes to just minutes
showMinutes = (show.getHours() * 60) + show.getMinutes();
// test to see if the show is going on right now
if (days[show.getDay()] === day && (showMinutes >= startMinutes && showMinutes <= endMinutes)) {
onAir = true;
}
return onAir;
}
// example: Air time is Tuesday between 1-2pm Central Time (-6)
var texasShowOnAir = onAir('Tuesday', '13:00', '14:00', '-6'));
// now check if we are on air
if (texasShowOnAir) {
// do stuff here...
}
You can now use this function like this:
var check = onAir('DAY', 'STARTTIME', 'ENDTIME', 'YOURTIMEZONE');
This will return a true/false. Be sure and use 24 hour format.
I would even argue that this is better than using your server's timestamp, because often (especially if you have shared hosting), your server can be set in a different timezone than you.
Here's a demo fiddle: http://jsfiddle.net/stevenschobert/mv54B/
Have the server provide a timestamp when it generates the page and have the client also generate a timestamp when it loads the page so that you can calculate the time offset between the two systems.
Then you can call a function on some interval that checks the current server time to see if it is within the 3pm-4pm period and show/hide the target elements as needed.
From the server:
<div id="server-timestamp" style="display:none">2013-02-12T18:01:19Z</div>
On the client:
$(document).on('load', function() {
var serverTime = new Date($('#server-timestamp').text())
, clientTime = new Date()
, offsetMilliseconds = (clientTime - serverTime);
setInterval(function() {
// If server time is 3pm-4pm then hide/show divs...
}, 1000 /* every second */);
});
I have divs that I want to display at specific times throughout the day. I have it working in PHP, but it requires refreshing the browser manually. I would like my script to automatically load the right div when the time is right.
Am I on the right track? Perhaps there is a jquery plugin for this sort of thing that would handle the refreshing?
Any help is greatly appreciated... Thanks!
<?php
$time = date("H\:i");
if (($time > "16:59") && ($time < "18:59")) {
echo "<div>1</div>";
}
elseif (($time > "18:59") && ($time < "20:59")) {
echo "<div>2</div>";
}
elseif (($time > "20:59") && ($time < "22:59")) {
echo "<div>3</div>";
}
else {
echo "<div id='out'><p>Outside the specified point in time.</p></div>";
}
?>
You won't need a jquery plugin to handle refreshing, you can just create a timer which checks every few minutes/seconds
#jasie was right to mention timers. He mentioned jquery timer, but you can just as well use regular javascript timers, like this (you tagged jquery, so I'll use jquery):
var timer = setInterval(function(){
var hour = (new Date()).getHours();
if (hour >= 17 && hour < 19) {
var $div = $('<div>1</div>');
} else if (hour >= 19 && hour < 21) {
var $div = $('<div>2</div>');
} else if (hour >= 21 && hour < 23) {
var $div = $('<div>3</div>');
} else {
var $div = $("<div id='out'><p>Outside the specified point in time.</p></div>");
}
$div.appendTo('body');
}, 2000); // checking every 2 seconds.
That should do the trick
I would use JQuery timer to poll every so often; when the time is right, use a $.load() to load in new information into the div on the page. You should do the time checks in Javascript, as you've done, so that you're not constantly transferring needless data between client and server.
Your backend should return a specific bit of html you want to display.
Your front-end should just be polling one specific url on the backend that returns this information.
(There are other ways to do it but this is my opinion)
As a start, using jQuery's AJAX call and a simple js timer. If page has one div with ID of "showithere", this willre-load your PHP page every 10 minutes:
<head>
<script>
function fn () {
alert ('now');
$("#showithere").load ("http://jsbin.com/help/");
}
</script>
</head>
<body onLoad="setTimeout (fn, 600000);" >