getHours() returning incorrect value

11,421

Solution 1

Try calling new Date(0).toString() and see if there is a timezone affecting it?

Mine gives

"Thu Jan 01 1970 02:00:00 GMT+0200 (FLE Standard Time)"

Because I am on GMT+2, so getHours gives 2 to me.

The Unix epoch is GMT+0

Use +new Date to get reliable milliseconds at a point in time and keep it as number. Do not do any math within an actual date object.

Here is what I have used:

var toTimeString = function( secs ) {
var days, hours, minutes, seconds;

    if( secs == null )
    return "";

days = ( secs / 86400 ) >> 0;
hours = ( secs % 86400 / 3600 ) >> 0;
minutes = ( secs % 3600 / 60 ) >> 0;
seconds = ( secs % 60 );    
seconds = seconds < 10 ? "0" + seconds : seconds;
minutes = minutes < 10 ? "0" + minutes : minutes;
hours = hours && hours < 10 ? "0" + hours : hours;

return "" + ( days ? days+" - " : "" ) + ( hours ? hours+":" : "" ) + minutes + ":" + seconds;      
};

Apply custom formatting as required.. This actually takes seconds so divide milliseconds by 1000 to get seconds.

Solution 2

I notice that, while people informed the User on how to fix his code, they did not inform him on how to do what he asked. The answer is pretty simple. Don't use function getHours(). Use getUTCHours(). This will bypass any timezone offset.

You'll still have problems if you ever need to go up to days, but, until then, the Date primitive will work just fine for what you use it for.

Solution 3

I know you're not asking for this, and it's annoying to get answers that don't address your question, but in this case... I'd seriously recommend switching to Datejs before you do much work noodling around with JS's native Date() object which isn't overly powerful and can be a source of many troubles, especially if you've got to normalize time zones! http://www.datejs.com/

Share:
11,421
Arnold
Author by

Arnold

Updated on June 07, 2022

Comments

  • Arnold
    Arnold almost 2 years

    I am using JavaScript Date object to convert milliseconds into a readable minutes:seconds formatted string. I need that to create a timer for a custom video player, where my JS interface receives the video duration info as a millisecond value.

    It’s been a fairly trivial task, before I decided to support a possibility of having a video longer than 59 minutes. And then I encountered this problem: when I submit a millisecond value to the new Date object’s constructor, and then call getHours(), it will return something even if the number of milliseconds stands for a period of time less than an hour. The easiest way to see this in action is to feed it, say, 0.

    enter image description here

    I‘d expect it to return 0, but it always returns 12 (13 in Opera, which makes it even more weird). Is this a normal behaviour or is it a bug? Either way, how do I reliably detect whether my millisecond value is limited to just minutes and seconds or also includes hours?

    Thanks.

    UPD:

    I‘ve tested it in Chrome 15 and Firefox 7 on OSX: same result as per the screenshot above. I cannot figure out how to use Opera Dragonfly console, but from what I see same thing happens in Opera, just with the value of 13 for getHours().

  • Arnold
    Arnold over 12 years
    Right, timezone. I am in New Zealand, so that’s why in my case it adds 12 hours to 0. Would never have thought about that, thanks a lot! Though it does not fix the problem, it just shows how unreliable this approach actually is…
  • gilly3
    gilly3 over 12 years
    That would be February 1st, 1900. Months are zero-based, Eg January is month 0.
  • GregL
    GregL over 12 years
    @gilly3 Good point, I forgot that. At any rate, the date is somewhat arbitrary. It is the time that is important in this case.
  • fubeca
    fubeca almost 11 years
    Thanks for this, GetUTCHours fixed my similar problem without the need for any other trickery.
  • Joshua Kemmerer
    Joshua Kemmerer about 6 years
    This should be the answer. Solved my issue, which was the same problem the original "asker" had.
  • Gabriel Pellegrino
    Gabriel Pellegrino almost 3 years
    You made me login again on github just to upvote you. That's the spirit. Perfect conduct.