首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使客户端javascript时钟与服务器日期同步的最佳方法

使客户端javascript时钟与服务器日期同步的最佳方法
EN

Stack Overflow用户
提问于 2009-10-29 00:20:26
回答 9查看 73.9K关注 0票数 67

我有一个任务,以显示在一些固定的时区(MSK或MSD -取决于当前日期)的HTML页面上的数字时钟(分钟精度)。我希望避免依赖客户端系统时钟,因此需要与服务器进行一些同步。HTTP服务器在每个响应中发送date头,所以我们可以发送一个AJAX GET或HEAD请求到我们网站的任何网址,以获得服务器日期,计算与客户端日期的差异,并使用它更新时钟与setTimeout()。还有其他问题仍然存在:日光设置的时区切换,非常慢的连接的延迟。

对这项任务有什么最简单的方法吗?我更喜欢在没有服务器端编程的情况下解决它。

EN

回答 9

Stack Overflow用户

回答已采纳

发布于 2009-10-29 02:00:50

如果您要使用ajax,那么应该记住readyState==2和readyState==3之间的客户端时间,因为服务器时间将设置在收到请求和准备响应的时间之间

票数 11
EN

Stack Overflow用户

发布于 2013-04-03 18:39:14

你可以在你的代码中使用NTP (Network Time Protocol)来计算精确的时间。

我试着向你解释:

发送请求时我们有发送请求的时间(例如4/3/2012 13:56:10.123)

  • You ClientTime to
  1. 对于请求我们有往返时间,我称之为RequestTime (例如:需要5秒)
  2. 在服务器中,我们计算服务器和客户端之间的差异时间(例如: It ServerTime - ClientTime = ServerClientDifferenceTimeWithRequestTime),你现在应该在步骤3中包括往返请求时间,然后你应该从Difference
  3. Server发送响应中删除往返时间,其中包括ServerClientDifferenceTimeWithRequestTime和ServerTime
  4. We对于响应,我称之为ResponseTime (例如:它需要3秒)
  5. ,我们再次计算服务器和客户端之间的差异时间(例如: it ServerTime - ClientTime = ServerClientDifferenceTimeWithResponseTime),再次说明:您现在应该计算这种差异,包括步骤6中的往返响应时间
  6. 我们现在在client
  7. 中有时间,您应该在client:

中计算简单的等式

X(SyncedTime) = Now + (ServerClientDifferenceTimeWithRequestTime - RquestTime)

X(SyncedTime) = Now + (ServerClientDifferenceTimeWithResponseTime - ResponseTime)

Now - ClientTime = RquestTime + ResponseTime =>

Now - (ServerClientDiffRq - RquestTime) = Now - (ServerClientDiffRs - ResponseTime)

如果你解决了这个问题,你会发现:

ResponseTime = (ServerClientDifferenceTimeWithRequestTime - Now + ClientTime + - ServerClientDifferenceTimeWithResponseTime )/2

然后你可以在客户端找到同步时间或服务器时间,公式如下:

X(SyncedTime) = Now + (ServerClientDifferenceTimeWithResponseTime - ResponseTime)

我展示了简单的代码,但是当你想写它的时候,不要忘记使用UTC的日期和时间函数……

服务器端(例如php、c#):

PHP:

代码语言:javascript
复制
header('Content-Type: application/json; charset=utf-8');
$clientTime = $_GET["ct"] * 1; //for php 5.2.1 or up: (float)$_GET["ct"];
$serverTimestamp = round(microtime(true)*1000); // (new DateTime())->getTimestamp();
$serverClientRequestDiffTime = $serverTimestamp - $clientTime;
echo "{\"diff\":$serverClientRequestDiffTime,\"serverTimestamp\":$serverTimestamp}";

C#:

代码语言:javascript
复制
long clientTime = long.Parse(Request.Form["ct"]);
long serverTimestamp = (DateTime.Now.Ticks-(new DateTime(1970,1,1) - DateTime.MinValue).Ticks) / 10000;
long serverClientRequestDiffTime = serverTimestamp - clientTime;
Response.Write("{\"diff\":"+serverClientRequestDiffTime+",\"serverTimestamp\":"+serverTimestamp+"}");

Javascript客户端(使用 ):

代码语言:javascript
复制
var clientTimestamp = (new Date()).valueOf();
$.getJSON('http://yourhost.com/getdatetimejson/?ct='+clientTimestamp, function( data ) {
    var nowTimeStamp = (new Date()).valueOf();
    var serverClientRequestDiffTime = data.diff;
    var serverTimestamp = data.serverTimestamp;
    var serverClientResponseDiffTime = nowTimeStamp - serverTimestamp;
    var responseTime = (serverClientRequestDiffTime - nowTimeStamp + clientTimestamp - serverClientResponseDiffTime )/2

    var syncedServerTime = new Date((new Date()).valueOf() + (serverClientResponseDiffTime - responseTime));
    alert(syncedServerTime);
});
票数 47
EN

Stack Overflow用户

发布于 2009-10-29 09:24:53

这两个Javascript函数应该可以为您完成此任务。

代码语言:javascript
复制
var offset = 0;
function calcOffset() {
    var xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
    xmlhttp.open("GET", "http://stackoverflow.com/", false);
    xmlhttp.send();

    var dateStr = xmlhttp.getResponseHeader('Date');
    var serverTimeMillisGMT = Date.parse(new Date(Date.parse(dateStr)).toUTCString());
    var localMillisUTC = Date.parse(new Date().toUTCString());

    offset = serverTimeMillisGMT -  localMillisUTC;
}

function getServerTime() {
    var date = new Date();

    date.setTime(date.getTime() + offset);

    return date;
}

编辑:删除了".replace(/^(.)\s\S/,“$1”)。

calcOffset()计算与服务器时间的偏移量并补偿格林尼治标准时间/协调世界时。

getServerTime()使用本地时区获取与服务器匹配的本地时间偏移量。

如果calcOffset()的执行时间很长,您可能会丢失一些秒精度。也许可以考虑执行时间...

如果您担心当本地时间或服务器时间更改为夏令时或从夏令时更改为夏令时时,计算的偏移量会出错,您可以在每个时钟小时后重新计算一点,系统将补偿夏令时的更改。可能需要等待,直到本地时钟和服务器时钟都过了一小时。

由于"Msxml2.XMLHTTP“,该示例仅在IE中有效。

票数 40
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1638337

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档