Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript Countdown Timer - Client Time vs mySQL Time

The following code is a countdown timer. It pulls an ending datetime stamp from mySQL and uses it to count to. The issue is that the mysql time may be in a different time zone than the client who is looking at the page with the timer.

I also pull the current timestamp from mySQL with NOW(), thinking that this would allow the timer to count as the user who created it intended.

if I put the NOW() value in this snippet

var timeDiff = target - (new Date()); 

like so

var nt='2015-03-11 05:12:15'.split(/[- :]/);
var timeDiff = target - (new Date(nt[0],nt[1]-1,nt[2],nt[3],nt[4],nt[5]));

the counter shows the correct time left when the page loads but does not count interactively any longer. I think I need to get the difference in hours between the clients local time and the mySQL NOW() and adjust the date in this line to get the interactive timer to run.

var timeDiff = target - (new Date());  

nothing I try seems to work.

This is the working script if the client happens to be int he same time zone.

 <script language="javaScript">              
  document.write(hrs);
  function timeDiff(target) {
    function z(n) {return (n<10? '0' : '') + n;}
    var timeDiff = target - (new Date()); 
    var hours    = timeDiff / 3.6e6 | 0;
    var minutes  = timeDiff % 3.6e6 / 6e4 | 0;
    var seconds  = timeDiff % 6e4 / 1e3 | 0;
    if (hours<0 || minutes<0 || seconds<0) {
      document.getElementById('divBody').style.display='none';
      document.getElementById('divExpired').style.display='';    
      return '<b>EXPIRED</b>';
      }
    else {
      return '<b>' + z(hours) + '</b> Hours, <b>' + z(minutes) + '</b>  Mins, <b>' + z(seconds) + '</b> Secs';
      }
    }
  function doCountDown(target) {
    document.getElementById('timer').innerHTML = '<img src=\"/backhaul/images/my/al-active.png\" class=\"vm2\" /> <span style=\"color:#c40000\"><b>EXPIRES IN</b></span>: ' + timeDiff(target);
    var lag = 1020 - (new Date() % 100);
    setTimeout(function(){doCountDown(target);}, lag);
    }
  window.onload = function() {
    //Insert Expiratin Date from mySQL into t var
    var t='2015-03-12 00:00:00'.split(/[- :]/);
    doCountDown(new Date(t[0],t[1]-1,t[2],t[3],t[4],t[5]));
  }
</script>
like image 522
chrisrth Avatar asked Aug 15 '26 12:08

chrisrth


1 Answers

There are many ways of doing this, but I'll elaborate on two ways.

Method 1 : Adjust the time on the client side

One way is what you are trying to do which is to get the current time of the server and find the difference with the client's current time. You can simply adjust the server target time to the client's time. This can be done with

var serverDifference=Date.parse(mysql_data.now)-Date.now()
var target=Date.parse(mysql_data.server_time_in_two_hours)-serverDifference

Then you can input it into your function without problem.

Method 2: Calculate the times remaining, server side

Since you just need a countdown timer, I think it's more appropriate to simply send the seconds left server side. This can be done with SQL using

 select timestampdiff(SECOND,now(),end_time) seconds_left from timers;

Then you simply just make a timer that counts down based on the number of seconds left instead of a target date. You can calculate the number of seconds left by deducting the time that the javascript has run from the time received from the server. So something like

var client_start=Date.now()
function timeDiff_fromseconds(target) {
    function z(n) {return (n<10? '0' : '') + n;}
    var timeDiff =target-(Date.now()-client_start)
    var hours    = timeDiff / 3.6e6 | 0;
    var minutes  = timeDiff % 3.6e6 / 6e4 | 0;
    var seconds  = timeDiff % 6e4 / 1e3 | 0;
    if (hours<0 || minutes<0 || seconds<0) {   
      return '<b>EXPIRED</b>';
      }
    else {
      return '<b>' + z(hours) + '</b> Hours, <b>' + z(minutes) + '</b>  Mins, <b>' + z(seconds) + '</b> Secs';
      }
}

There is also performance.now() as suggested by @dandavis. This returns the number of milliseconds since the tab opened and is accurate to 1/1000th of a millisecond. And this doesn't change even if the system clock of the client browser changes. For full support, you should use a polyfill (As of the time of this writing, iOS Safari doesn't support it). In this context we can replace Date.now() with it.

JSFiddle Demo:

http://jsfiddle.net/3o3u5r5j/1/

like image 90
mfirdaus Avatar answered Aug 18 '26 02:08

mfirdaus



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!