The best way to synchronize client-side javascript clock with server date

Viewed 78572

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.

9 Answers

Little too late but hope this might help someone!

I had a similar requirement to display a server clock irrespective of client's machine. So basically, you just play with three parameters here:

x = clientReqTimestamp = (new Date()).valueOf();  //Client Timestamp at request.
y = serverTimestamp;  //query your server for Unix Timestamp.
z = clientRespTimestamp = (new Date()).valueOf();  //Client Timestamp on receiving response.

Then do the below calculation:

var reqElapsed = Math.abs(y - x);  //time taken in milliseconds to hit the server
var respElapsed = Math.abs(z - y);  //time taken in milliseconds to get response from server
var serverNewTime = z + respElapsed;  // Voila! actual server time.

Below is the full code in action:

<script>
       
    var clientTimestamp = (new Date()).valueOf();
    
    var Data = {
        OperatorMobileNo: 'XXXXXXXXXX',
        requestClientTime: clientTimestamp
    };
    $.ajax({
        type: "POST",
        url: serviceURLx + "/XXXX/GetServerDateTime/1.0",
        dataType: "JSON",
        data: JSON.stringify(Data),
        contentType: "application/json; charset=utf-8",
        success: function (responseData) {
            debugger;
            var responseJSON = JSON.parse(JSON.stringify(responseData));
            if (responseJSON.ResponseCode === "000") {
    
                var x = clientReqTimestamp = clientTimestamp;
                    // If server time is in seconds => multiply by 1000 to convert sec to milli
                var y = serverTimestamp = responseJSON.Response.ServTimestamp * 1000;
                var z = clientRespTimestamp = (new Date()).valueOf();
                
                var reqElapsed = Math.abs(y - x);
                var respElapsed = Math.abs(z - y);

                var serverNewTime = z + respElapsed;
                
                debugger;
                //Init Server Clock
                setInterval( function() {
                    debugger;
                    var servClockT = new Date(serverNewTime += 1000);
                    document.getElementById('serverClock').innerHTML = servClockT;
                }, 1000);
            }
            else {
                swal("", "Unable To Fetch Server Time!", "info");
                console.log(responseJSON.ResponseCode);
            }
        },
        error: function () {
        }
    });
</script>

If I understand question correctly we have only 3 values

  1. clientTimeWhenRequestSent
  2. serverTime
  3. clientTimeWhenResponseReceived

if assume request and response time are equal we can calculate timeDifference between server and client by:

const diff = serverTime - clientTimeWhenRequestSent 
- (clientTimeWhenResponseReceived - clientTimeWhenRequestSent)/2;

and get correct time on client with help of

const correctClienTime =  (new Date()).valueOf() + diff;
Related