Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Moment.js issue adding days with Daylight Savings Time

In Moment.js I have the next problem:

1.I create a moment date:

var m = moment(new Date(2014, 9, 18, 0, 0, 0));

2.If I call toString function:

m.toString() //"Sat Oct 18 2014 00:00:00 GMT-0300"

3.Now, I add one day I have the next output:

m.add("days",1).toString() //"Sat Oct 18 2014 00:00:00 GMT-0300"

What I get 18 again? Momentjs should change the date.

EDIT: Issue in Chrome 32.0.1700.76 m

EDIT2: MomentJs version 2.5.1

EDIT3: Timezone UTC-3

like image 855
earnaz Avatar asked Jan 23 '14 20:01

earnaz


People also ask

Does moment JS handle Daylight Savings?

js isDST() Function. It is used to check daylight saving time in Moment. js using the isDST() function. This function checks if the current moment is in daylight saving time.

What problems are caused by daylight savings time?

During the week after the shift to DST, research shows an associated rise in: Cardiovascular disease, with a 24% higher risk of heart attacks. Injuries, including a 6% spike in fatal car accidents. Stroke rate, which increases by 8%

Why is daylight savings on different days?

The main purpose of Daylight Saving Time (called "Summer Time" in many places in the world) is to make better use of daylight. We change our clocks during the summer months to move an hour of daylight from the morning to the evening. Countries have different change dates.

Why is adjusting to daylight savings difficult?

In general, "losing" an hour in the spring is harder to adjust to than "gaining" an hour in the fall. It's similar to airplane travel; traveling east we lose time. An "earlier" bedtime may cause trouble falling asleep and increased wakefulness during the early part of the night.


3 Answers

General remark to avoid issues like this (as you can see, they do happen, and are sometimes happening due to a browser bug): if you represent a day using Date object, you can just have a convention to pass noon (12h00) instead of midnight (00h00) to the Date constructor, and then in the function that prepares date for display, cut it off.

The bugs in browsers, and issues due to DST usually shift the time by one hour (time goes back from 00h00 to 23h00 the previous day). If you just use midday, it should not happen (in case of similar bugs, time will go back from 12h00 to 11h00 for instance, but the day will not change).

(Of course you need to remember that the date is noon when you pass it around, sometimes it might not be good)

For instance, have a look at this bug in YUI library which we were using in on of our company apps:

https://github.com/yui/yui2/pull/15

This happened only in Firefox, only on Windows, only in particular timezone, and only in particular month. But it did happen.

like image 52
jakub.g Avatar answered Oct 17 '22 15:10

jakub.g


I have looked at you code and at first I did not get the same results. However when I changed the timezone to Brazil (GMT-03:00) - Sao Paulo I got the same result. This is clearly a bug and has now been traced to V8 and reported.

Plunker

var m = moment(new Date(2014, 9, 18, 0, 0, 0));
console.log(m.toString());
console.log(m.add("days",1).toString());

Sat Oct 18 2014 00:00:00 GMT-0300 script.js:4

Sat Oct 18 2014 00:00:00 GMT-0300 script.js:5

I have submitted a bug: https://github.com/moment/moment/issues/1440

Update

Moment.js is not responsible for this bug. It has been tracked to a bug in V8 (the javascript engine used by both Chrome and Node). I have filed a bug with V8 that you can follow here: https://code.google.com/p/v8/issues/detail?id=3116

Here is the work that Isaac Cambron did to track it down.

OK, reproduced now in both Ubuntu and OSX (I was using a different Brazilian city in my tests before). I'm using Node, not Chrome, but for our purposes V8 is V8.

moment([2014, 9, 18]).add(1, 'd').format(); //=> '2014-10-18T00:00:00-03:00'

The problem is that Moment essentially does this:

var d = new Date(2014, 9, 18);
d.setDate(19);
d.toString(); // => Sat Oct 18 2014 23:00:00 GMT-0300 (BRT)
//wtf?

Then it sets the hours to zero. Since V8 weirdly sets the time to late on Oct 18 even though we specifically asked it to set it to Oct 19, the answer comes out wrong. This is all especially weird because the DST transition here is a jump forward, meaning if anything it should end up 1:00, not 23:00 the previous day.

In fact, it even does this:

new Date("October 18, 2014"); //=> Sat Oct 18 2014 00:00:00 GMT-0300 (BRT)
new Date("October 19, 2014"); //=> Sat Oct 18 2014 23:00:00 GMT-0300 (BRT)
like image 33
Nathaniel Johnson Avatar answered Oct 17 '22 13:10

Nathaniel Johnson


According to this jsFiddle, what you're doing /should/ be working. What browser are you testing in?

http://jsfiddle.net/mori57/Nq3KD/

var m = moment(new Date(2014, 9, 18, 0, 0, 0));
console.log(m.toString()); // Firebug output: Sat Oct 18 2014 00:00:00 GMT-0400
console.log(m.add("days",1).toString()); // output: Sun Oct 19 2014 00:00:00 GMT-0400
like image 21
Jason M. Batchelor Avatar answered Oct 17 '22 13:10

Jason M. Batchelor