Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

getHours() returning incorrect value

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().

like image 405
Arnold Avatar asked Nov 15 '11 00:11

Arnold


2 Answers

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.

like image 59
trlkly Avatar answered Oct 05 '22 16:10

trlkly


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.

like image 42
Esailija Avatar answered Oct 05 '22 15:10

Esailija