Closed Bug 1254041 Opened 10 years ago Closed 7 years ago

Date.prototype.setMilliseconds doesn't work correctly with negative time on ICT(UTC+7)

Categories

(Core :: JavaScript Engine, defect)

38 Branch
defect
Not set
normal

Tracking

()

RESOLVED DUPLICATE of bug 1346211

People

(Reporter: lamerstar, Unassigned)

References

Details

Attachments

(3 files)

User Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Firefox/38.0 Build ID: 20160307055558 Steps to reproduce: I created a date like this: var h = new Date(Date.UTC(1969, 11, 31, 23, 0)) This gives a date with a negative milliseconds count -3600000 Trying to append 30 minutes will change the date to -1800000, changing the date again with 30 minutes will move the date back to -3600000 Actual results: If we try to add 30 minutes in a loop from a negative date, it will result in an infinite loop moving from -3600000 to -1800000, from -3600000 doing h.setHours(h.getHours() + 1) will not change the date at all. Expected results: The date should have move 30 minutes forward or 1 hours forwards for hours... in milliseconds it should have reached "0". Instead it goes back 1 hours backwards. I tried to setHours(getHours() + 2) from -3600000 millis and it moves to 0. As if there was a leap hour.
This affect a quite common library fullcalendar.js, there is a method named "addMinutes" that uses the behaviour of adding minutes to change the hour... except it creates an infinite loop with this bug. A quick fix to this bug is to replace the method addMinutes with this: function addMinutes(d, n) { n *= 60000; if (d.getTime() + n === 0){ d.setTime(0); } else { d.setMinutes(d.getMinutes() + n); } return d; }
Can you post a full testcase? How does the loop look like? I cannot reproduce the issue with following code: var h = new Date(Date.UTC(1969, 11, 31, 23, 0)); for (var i = 0; i < 5; i++) { console.log(h.toUTCString()); console.log(h.getTime()); h.setMinutes(h.getMinutes() + 30); } it gives following output on Firefox ESR 38.6.1, the value of h.getTime() doesn't get back to -3600000. > "Wed, 31 Dec 1969 23:00:00 GMT" > -3600000 > "Wed, 31 Dec 1969 23:30:00 GMT" > -1800000 > "Thu, 01 Jan 1970 00:00:00 GMT" > 0 > "Thu, 01 Jan 1970 00:30:00 GMT" > 1800000 > "Thu, 01 Jan 1970 01:00:00 GMT" > 3600000 Also, the addMinutes function you posted looks buggy, it adds |n * 60000| minutes.
Flags: needinfo?(lamerstar)
yes, the addMinutes should be: function addMinutes(d, n) { if (d.getTime() + (n * 60000) == 0) { d.setTime(0) } else { d.setMinutes(d.getMinutes() + n); } return d; } I'm on Firefox 38.6.1 too. Could it be caused by some optimizations? Technically, it should be a bug in SpiderMonkey and not firefox... I have spidermonkey 24.2.0 installed.
Flags: needinfo?(lamerstar)
are you running the script on spidermonkey 24.2.0, or on Firefox 38.6.1? also, please post a full testcase, not only addMinutes function.
Flags: needinfo?(lamerstar)
Attached file scratchpad.js
Test Case
Flags: needinfo?(lamerstar)
Screenshot of results
Component: Untriaged → JavaScript Engine
Product: Firefox → Core
It's not reproducible here. I get following output: -1 0 1 0 -1 0 3600000 10799999 10800000 18000000 on following configurations: * Firefox ESR 38.6.1 64bit on OSX 10.11.3 (timezone: Japan) * Firefox ESR 38.6.1 64bit on Debian GNU/Linux 8.3 (timezone: Asia/Tokyo) It could be a timezone issue (daylight saving time?). which timezone are you using?
Flags: needinfo?(lamerstar)
Ok, I just tried with other timezones and that could be the real reason... I can't reproduce the bug with other timezones... I'm in ICT(UTC+7) Ho Chi Minh. I checked on the net, and couldn't find a reason in 1969 or 1970 for that one hour leap between 1969 and 1970. I can add my /etc/localtime file to reproduce the bug.
Flags: needinfo?(lamerstar)
Attached file localtime
Confirmed the issue with your localtime file, on Firefox 38.6.1 (64bit) on Fedora 23. It happens also on Nightly Firefox (64bit) and js shell (64bit) for today's mozilla-central.
Status: UNCONFIRMED → NEW
Ever confirmed: true
Summary: setMinutes doesn't work correctly → Date.prototype.setMilliseconds doesn't work correctly with negative time on ICT(UTC+7)
I also should add that the issue isn't present on Chromium.
Also, the title might be a bit misleading. It affects all of setMilliseconds, setSeconds, setMinutes, setHours and probably setYears ... anything that modify the time seems to be affected.
looks like it's a issue related to Daylight Saving Time and maybe our implementation for it. var a = new Date(0); console.log(a); a = new Date(-1); console.log(a); output is following: Thu Jan 01 1970 08:00:00 GMT+0800 (IDT) Thu Jan 01 1970 06:59:59 GMT+0700 (IDT) so, that "1 hour" difference seems to be related.
Blocks: 285663
Dup'ing forward to bug 1346211 which should have fixed this problem. Please reopen if the issue is still present. Thanks!
Status: NEW → RESOLVED
Closed: 7 years ago
Resolution: --- → DUPLICATE
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: