Javascript 倒数计时器 - 客户端时间与 mySQL 时间

Javascript Countdown Timer - Client Time vs mySQL Time

本文关键字:时间 mySQL 客户端 倒数 计时器 Javascript      更新时间:2023-09-26

以下代码是一个倒数计时器。它从 mySQL 中提取一个结束日期时间戳并使用它来计数。问题是 mysql 时间可能与使用计时器查看页面的客户端位于不同的时区。

我还使用 NOW() 从 mySQL 中提取当前时间戳,认为这将允许计时器计入创建它的用户的意图。

如果我把 NOW() 值放在这个代码段中

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

这样

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]));

计数器显示页面加载时剩余的正确时间,但不再以交互方式计数。我想我需要获取客户端本地时间和 mySQL NOW() 之间的小时差,并调整此行中的日期以使交互式计时器运行。

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

我尝试的任何东西似乎都不起作用。

如果客户端碰巧在同一时区,则这是工作脚本。

 <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>

有很多方法可以做到这一点,但我会详细说明两种方法。

方法1:调整客户端的时间

一种方法是您尝试执行的操作,即获取服务器的当前时间并找到与客户端当前时间的差异。您可以简单地将服务器目标时间调整为客户端的时间。这可以通过

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

然后,您可以毫无问题地将其输入到函数中。

方法 2:计算服务器端的剩余时间

由于您只需要一个倒数计时器,因此我认为简单地发送服务器端左侧的秒数更合适。这可以通过 SQL 完成,使用

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

然后,您只需制作一个计时器,该计时器根据剩余的秒数而不是目标日期进行倒计时。您可以通过从从服务器接收的时间来计算剩余的秒数。所以像

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';
      }
}

@dandavis建议也有performance.now()。这将返回自选项卡打开以来的毫秒数,精确到毫秒的 1/1000。即使客户端浏览器的系统时钟发生变化,这也不会改变。为了获得完全支持,您应该使用polyfill(截至撰写本文时,iOS Safari不支持它)。在这种情况下,我们可以用它替换Date.now()

JSFiddle Demo:

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

如果可以从数据库中获取剩余秒数而不是到期时间(意味着在服务器上计算它并发送到客户端)。然后,可以使用以下代码(示例)。小提琴

var countDownId;
var timer;
function countDown(){
    console.log(timer--);
    if(timer<=0){
        clearInterval(countDownId);
        alert('time expired');
    }
}
function startCountDown(secondsToExpire){
    var milliseconds = 1 * 1000 ;// 1 second
    timer = secondsToExpire;
    countDownId = setInterval(function() { countDown();},milliseconds);
}
  window.onload = function() {
    //Insert remaining time from expiration
    var timeRemaining = 5;
    startCountDown(timeRemaining);
  }

您可以调整此设置以满足您的需求。