earnaz
earnaz

Reputation: 435

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

Upvotes: 13

Views: 19014

Answers (6)

Memphis335
Memphis335

Reputation: 345

You should pass the number first and then the "days"

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

Tested in Chrome Version 50.0.2661.37 beta-m (64-bit)

Upvotes: 1

jakub.g
jakub.g

Reputation: 41238

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.

Upvotes: 1

Jan
Jan

Reputation: 43169

This is a rather old post but I got here via Google with the same issue. What I ended up using was the following code, maybe this is helpful for someone else:

    var then = moment("23.07.2014", "DD.MM.YY");
    var before = moment.unix(then.unix()-86400); // 86400 seconds/day
    var after = moment.unix(then.unix()+86400);

Upvotes: 1

Akalya
Akalya

Reputation: 906

Simply you can use the below code to get next date in moment.js

var date='2014/09/18';
var nextDate = moment(date, 'YYYY/MM/DD').add('days', 1).format('YYYY/MM/DD');
console.log(nextDate); // 2014/09/19

For more details , look at below link

momentjs docs

Upvotes: 3

Nathaniel Johnson
Nathaniel Johnson

Reputation: 4839

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)

Upvotes: 16

Jason M. Batchelor
Jason M. Batchelor

Reputation: 2951

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

Upvotes: 3

Related Questions