Javascript clock - server time
I need to show the server time on the clock. Below is the code I have. I am getting the server time using an Ajax call. The problem is, if the user changes the local / computer clock, it will also update the script clock, which doesn't fit - it should continue unchanged and I am stuck. I've tried passing serverTime to setTimeout so it is used as a reference every time but no luck with that.
var serverTime = 1490856278000;
var localTime = +Date.now();
var timeDiff = serverTime - localTime;
var realTime;
var date;
var hours;
var minutes;
var seconds;
setInterval(function () {
realTime = +Date.now() + timeDiff;
date = new Date(realTime);
hours = date.getHours();
minutes = date.getMinutes();
seconds = date.getSeconds();
document.getElementById('clock').innerHTML = hours + ':' + minutes + ':' + seconds;
}, 1000);
<div id="clock"></div>
You can compare each realTime
to the last in yours setInterval
. If the difference is far from 1000ms which it should be, make an ajax call to request server time again and update timeDiff
.
Also you can try using performance.now
instead Date.now
. Higher resolutions are unnecessary and possibly costly, but MDN claims that
as opposed to the
Date.now()
values ββreturnedPerformance.now()
are always increasing at a constant rate, regardless of the system clock (which may be manually adjusted or corrupted by software such as NTP)
Using How to create an accurate timer in javascript? and Bergi's answer, I prepared another way. I think you don't need to use local time at all:
var serverTime = 1490856278000;
var expected = serverTime;
var date;
var hours;
var minutes;
var seconds;
var now = performance.now();
var then = now;
var dt = 0;
var nextInterval = interval = 1000; // ms
setTimeout(step, interval);
function step() {
then = now;
now = performance.now();
dt = now - then - nextInterval; // the drift
nextInterval = interval - dt;
serverTime += interval;
date = new Date(serverTime);
hours = date.getUTCHours();
minutes = date.getUTCMinutes();
seconds = date.getUTCSeconds();
document.getElementById('clock').innerHTML = hours + ':' + minutes + ':' + seconds;
console.log(nextInterval, dt); //Click away to another tab and check the logs after a while
now = performance.now();
setTimeout(step, Math.max(0, nextInterval)); // take into account drift
}
<div id="clock"></div>
The time will change because it Date.now();
gets the time from the client machine. There are no AJAX calls in your script.