views:

1316

answers:

4

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.

A: 

I'd only request the update from the server every 30s or so, if you require precision only to the minute. Don't rely on the client time at all, but use their system clock to keep the clock accurate between updates. I think you answered your own question?

It would help if we better understood what you're actually trying to do.

If you simply want a clock to display the time on the server, which is then adjusted to a certain timezone, do it clientside with offsets. Handle DST in the timezones it is applicable by using the date you receive from the server as well. If you want to determine latency, you would probably need a small script on the server to calculated the difference. But as above, it would help to understand the problem better. If precision is only to the minute, latency seems less critical.

snicker
Single synchronization is enough to get the difference. The question was about properly handling timezone and accounting latency, or a better way to solve the problem.
Denis Otkidach
Then the question is not very clear, as doubly indicated by the commenter thinking the asker wanted to change the client clock.
snicker
I believe "to show digital clock" means some HTML markup with javascript updating it.
Denis Otkidach
A: 

I would sync the time during initialization with Internet Time Server.

http://tf.nist.gov/service/its.htm

Yan Cheng CHEOK
from javascript?
n0s
+3  A: 

you should remember client time between readyState==2 and readyState==3 if you are going to use ajax, because server time will be set somewhere between time on request recieved and response prepared

barbuza
Any example with jquery or some other JS framework hiding difference in AJAX implementation?
Denis Otkidach
i didn't provided example using jquery/mootools/prototype because them all are hiding work with browser's native xmlhttprequest object and don't provide interface for handling readystatechange events
barbuza
+3  A: 

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(/^(.)[\s\S]/,"$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.....

Fedearne
what this strange regexp is meant to do: `.replace(/^(.*)[\s\S]*/,"$1")` ?
n0s
I actually copied that part from some old source. The author doesn't remember what is does and i doesn't even appear to valid regex....Sorry about that....
Fedearne