jaunt
jaunt

Reputation: 5086

Javascript's date object toLocaleTimeString adds an hour

I'm trying to create a timer from when the user clicks a button. To do this I tried to calculate the difference between two date objects. When I output the difference, it works. However thetoLocaleTimeString call returns a string with an extra hour added:

var start;
var timer;
function myTimer() {
  var current = new Date();
  var difference = new Date(current - start);
  console.log(difference.getTime(), difference.toLocaleTimeString(navigator.language));
  document.getElementById("timer").innerHTML = difference;
  document.getElementById("timer2").innerHTML = difference.toLocaleTimeString('en-GB');
}
start = new Date();
timer = setInterval(myTimer, 1000);
draw();
<h1 id="timer"></h1>
<h1 id="timer2"></h1>

What am I doing wrong?

Upvotes: 6

Views: 3614

Answers (2)

somethinghere
somethinghere

Reputation: 17350

Because of the problems with JS and timezones, you are better of using something like moment.js's timezone (http://momentjs.com/timezone/) to do correct conversions (that keep in mind the shift of BST, GMT, differences between countries, etc..). For the purpose of your timer, the following would work as well, and is more accurate as well as simpler to reason about:

// Use Date.now() to get the time in milliseconds for this local computer
var start = Date.now();
var time  = new Date();
// This function will prepend a 0 to a number lower than 10
function prependZero(v){
  if(v < 9) return '0' + v;
  else return v;
}
var timer = setInterval(function() {
    // Calculate the difference using the computers local time strings
    var difference = new Date(Date.now() - start);
    document.getElementById("timer").innerHTML = new Date();
    // Now use the Date mnethods to get the correct output:
    document.getElementById("timer2").innerHTML = prependZero(difference.getHours()) + ':' + prependZero(difference.getMinutes()) + ':' + prependZero(difference.getSeconds());
}, 1000);
<h1 id="timer"></h1>
<h1 id="timer2"></h1>

Upvotes: 1

Drew Gaynor
Drew Gaynor

Reputation: 8472

Specify the time zone as UTC in the options argument. Otherwise, the difference date will be adjusted to the user agent's time zone.

document.getElementById("timer2").innerHTML = difference.toLocaleTimeString('en-GB', { timeZone: 'UTC' });

Read more on the options argument and toLocaleTimeString in the MDN documentation.

var start;
var timer;
function myTimer() {
  var current = new Date();
  var difference = new Date(current - start);
  console.log(difference.getTime(), difference.toLocaleTimeString(navigator.language));
  document.getElementById("timer").innerHTML = difference;
  document.getElementById("timer2").innerHTML = difference.toLocaleTimeString(navigator.language, { timeZone: 'UTC', hour12: false });
}
start = new Date();
timer = setInterval(myTimer, 1000);
draw();
<h1 id="timer"></h1>
<h1 id="timer2"></h1>

Upvotes: 5

Related Questions