side javascript clock with server date

I have a task to show digital clock (with minutes precision) on HTML page in some fixed timezone (MSK or MSD - depending on current date). I'd like to avoid relying on client system clock, so some synchronization with server is required. HTTP server sends Date header in each response so we can send an AJAX GET or HEAD request to any URL of our site to get server date, calculate the difference with client date and use it when updating clock with setTimeout(). There are other issues remains: timezone switching for daylight settings, latency accounting for very slow connections.

Any idea to this task the simpliest way? I'd prefer to solve it without server-side programming.


如果你打算使用ajax,你应该记住readyState == 2和readyState == 3之间的客户端时间,因为服务器时间将根据请求接收和响应准备之间的某个时间设置


These two Javascript functions should do the trick for you.

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

EDIT: removed ".replace(/^(.)[sS]/,"$1")".

calcOffset() calculates the offset from server time and compensates for GMT/UTC.

getServerTime() to get the local time offset to match the servers, using the local timezone.

If calcOffset() takes along time to execute you might loose some seconds precision. Maybe the execution time could be taken into account....

If you are worried about the calculated offset becoming wrong when either local time or server time change to or from daylight savings time you could recalculate a litle after every clock-hour, the system will compensate for changes in dayligt savings time. It might be necessary to wait until both the local and server clock has passed the hour.

The example only works in IE because of "Msxml2.XMLHTTP" i think.....


You can calculate exact time with NTP (Network Time Protocol) in your codes,

i try to explain for you:

  • We have ClientTime on Sending Request (for example 4/3/2012 13:56:10.123)
  • You send ClientTime to Server
  • We have Round-trip time for request, i called it RequestTime (for example: It takes 5 seconds)
  • In Server, We calculate Difference time between Server and Client (for example: It ServerTime - ClientTime = ServerClientDifferenceTimeWithRequestTime), you should now this Difference including Round-trip request time in step 3 then you should remove round trip time from Difference
  • Server Send response that include ServerClientDifferenceTimeWithRequestTime and ServerTime
  • We have Round-trip time for response, i called it ResponseTime (for example: It takes 3 seconds)
  • In client, We calculate Difference time between Server and Client again (for example: It ServerTime - ClientTime = ServerClientDifferenceTimeWithResponseTime), again: you should now this Difference including Round-trip response time in step 6
  • We have Now time in Client
  • You should Calculate simple equations in client:
  • X(SyncedTime) = Now + (ServerClientDifferenceTimeWithRequestTime - RquestTime)

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

    Now - ClientTime = RquestTime + ResponseTime =>

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

    if you solve it you found this:

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

    and then you can found synced time or server time in client with this equation:

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

    I show simple code but when you want write it don`t forgot use UTC date & time functions...

    Server Side (for example php, c#):

    PHP:

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

    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+"}");
    

    Client Side (Javascript with Jquery):

    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);
    });
    
    链接地址: http://www.djcxy.com/p/86162.html

    上一篇: 服务器和客户端分页究竟是什么?

    下一篇: 服务器日期的一面JavaScript时钟