views:

46

answers:

6

How can I write a script to detect when a user changes their system time in JS?

A: 

Do you mean if they are changing their own system time to something that is wrong? You can ask the user for their time zone and get the correct time from the server, and then compare it to the user's system time.

thenickperson
My page has generated events at the exact time. When the user changes his system time, then skip several events for example.
yomash
+1  A: 

There is no (portable) way to track a variable in JavaScript. Also, date information does not lie in the DOM, so you don't get the possibility of a DOM event being triggered.

The best you can do is to use setInterval to check periodically (every second?). Example:

function timeChanged(delta) {
  // Whatever
}

setInterval(function timeChecker() {
  var oldTime = timeChecker.oldTime || new Date(),
      newTime = new Date(),
      timeDiff = newTime - oldTime;

  timeChecker.oldTime = newTime;

  if (Math.abs(timeDiff) >= 5000) { // Five second leniency
    timeChanged(timeDiff);
  }
}, 500);
strager
That's exactly it. Thanks. But the shift back time, nothing happens.
yomash
@yomash, This may be a Windows or Chrome issue; I noticed it took a while to propagate changes back in time myself. It does happen, however, but just a few seconds later than you would expect.
strager
yes, chrome issue (on ubuntu). Thank you.
yomash
A: 

Don't think there is a solution to what you are asking for but you can get the users timezone offset.

new Date().getTimezoneOffset() * -1

This returns the offset in minutes from GMT. Bare in mind though this does not take DST into consideration.

Liam Spencer
+1  A: 

Check in an interval function that the time has not changed too much:

function getTime()  {
  var d = new Date();
  return d.getTime();
}

function checkTime()  {
  if (Math.abs(getTime() - oldtime) > 2000)  {  // Changed by more than 2 seconds?
    alert("You changed the time!");
  }
  oldtime = getTime();
}

var oldtime = getTime();
setInterval(checkTime, 1000);  // Check every second that the time is not off

Tested on Windows with Opera & FF and works flawlessly.

dark_charlie
My bad, didn't read the code carefully enough.
mattbasta
+1  A: 
var last_time = new Date().getTime();
setInterval(function() {
    var time = new Date().getTime();
    var offset = time - last_time;
    if(offset < 0 || offset > 1500) {
        // Time has been changed
    }
    last_time = time;
}, 1000);

In theory, this should work. It will check every second to make sure the time hasn't been changed. Note that I use 1100 milliseconds as most JS interpreters don't fire off events at exactly the time specified.

Hope this helps!

mattbasta
A: 

You could check every 30 seconds, etc. If the new Time is off by more than 30 seconds +/- some threshold, you could do a more exhaustive comparison to determine how much it has been changed.

Derrick