Moment.js issue adding days with Daylight Savings Time - javascript

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

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)

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

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

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);

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.

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)

Related

How to get time in range of two hours no matter which day?

I am using momentjs and its plugin moment-range, I want to get time in range of two hours no matter which day.
For example,
Jan 9, 2014 08:30am
Jan 1, 2015 10:00am
Feb 5, 2016 08:30am
Say I want to get between 8am to 9am. The result I want is
Jan 9, 2014 08:30am
Feb 5, 2016 08:30am
Can someone give me some hint? Thanks
I would just use moment.get('hour') and moment.get('minute') of each and do some simple math comparisons

How to create dates in another timezone, in browser Javascript

I have a client side web application where the user must create Dates for timezones other then their own, and I'm not sure of the best way to do this.
Using Moment Timezone, I know how I can change a time into another timezone. That is, convert Nov 18 2013 11:00:00 GMT-0500 to Nov 19 2013 03:00:00 GMT+1100. These still represent the same absolute time, but just with a different 'view'.
What I need to do is convert, respecting daylight savings, Nov 18 2013 11:00:00 America/Toronto" to Nov 18 2013 11:00:00 Australia/Sydney (which are different absolute times).
So far the only way I can come up with is to create a Date, serialize it to string, and then parse it with Moment Timezone, something like:
localEvent = new Date(2015, 03, 10, 18, 30)
eventStr = localEvent.toString().split('GMT')[0]
# eventStr = 'Fri Apr 10 2015 18:30:00'
event = moment.tz(eventStr, 'Australia/Sydney')
So now this code will create the exact same point in time regardless of which timezone the browser is operating in.
But this feels very hacky, is there a better way to do this?
Yes, you can do that better:
var zone = moment().tz('Australia/Sydney');
var c = moment(new Date(2015, 03, 10, 18, 30));
c.utcOffset(zone.utcOffset(), true);
// ^--- this flag keeps the same time
// while shifts a timezone
console.log(c.format());
JSFiddle: http://jsfiddle.net/8m6rdzqj/
How I found it: I just went through the moment and moment-timezone source: https://github.com/moment/moment-timezone/blob/master/moment-timezone.js#L347

toJSON function from Date object substracting one day

I'm doing some date manipulation in javascript using Date object.
I lost like one hour to understund a bug : Right after initialization, I used .toJSON() function and my date was decremented by one. Here's a code sample of what I was doing :
var date = new Date();
console.log(date.getDate()); // print "19"
date.setDate(date.getDate()-1); // print "18"
var formated = date.toJSON().substr(0, 10); // print "2013-09-17"
Suddenly the date moved from 18 to 17.
So to be sure I tried this directly into the developer console :
new Date(2013, 09, 19)
Sat Oct 19 2013 00:00:00 GMT+0200 (Paris, Madrid (heure d’été)) // date "19" as it should
new Date(2013, 09, 19).toJSON()
"2013-10-18T22:00:00.000Z" // date "18" as it shouldn't
Now my question is simply "why ?".
Is it possible that this come from my configuration or else ?
Is it a bug ? If yes is it a known bug ?
If you look more carefully :
new Date(2013, 09, 19);
=> Sat Oct 19 2013 00:00:00 GMT+0200 (CEST)
Two things are important here :
The hour : 00:00:00
The Timezone : +0200
When you then call .toJSON, it will convert it in GMT + 0.
So 00:00:00 - 2hr = Today -1, hour being 22:00:00.
Now take a look at :
new Date(2013, 09, 19).toJSON()
=> "2013-10-18T22:00:00.000Z"
One day before, but hour set to 22:00:00
That's the reason : switching from GMT+0200 to GMT+0.
Now for the solution, someone already asked it : Javascript Date.toJSON don't get the timezone offset ;)
Absolutely no bug here, just checkout the timezone.
The JSON string is in GMT (that's what the Z at the end means). Your local time is two hours ahead of that. So midnight on the 19th in your timezone is 22:00 on the 18th in GMT.
It's because of the -2 hours time offset.
Try to do
YourDate.setHours(0, -YourDate.getTimezoneOffset(), 0 0);
It will be a correct date.

DST problem storing date in Javascript Date object

I have this simple Javascript code
var d = new Date(2011, 9, 8);
alert(d); // Show: Fri Oct 7 23:00:00 UTC-0400 2011
Important: My Time Zone is "Santiago de Chile", and I set computer clock to: 2-Oct-2011.
Alert show that Day is 7!!... why? How I can get it right? (Problem is only in this day)
According to this page DST change in Chile is always at the second full weekend of October and starts at midnight (lets disregard the extended DST of this year, as it's very likely your computer doesn't know about it).
That means that, as is also shown using the script I linked to earlier, at your timezone 8 Oct 2011 midnight can't be represented in UTC-0300, so it automatically switches to UTC-0400 to represent the same time.
I can reproduce your issue in my timezone (Amsterdam, UTC+1/2h) by asking for Sun 27 March 2011, 2:00 AM (with current timezone CEST=UTC+0200) (at which time summer time (CEST) starts and the clock is adjusted from UTC+0100 to UTC+0200) (remember this is exactly the opposite on the northern hemisphere))
new Date(2011, 2, 27, 2, 0, 0, 0);
which effectively can't be represented in UTC+0200, so the system chooses UTC+0100 and outputs
Sun Mar 27 2011 01:00:00 GMT+0100 (CET)
So, it's the same time in Unix time, only represented differently in your local timezone.
And yes, I know 8 October is a Saturday and DST change starts at Sunday, midnight, but this is the closest I can get.
Update: I can now reproduce your issue by setting the timezone of a WinXP machine to Santiago and let the OS automatically adjust for DST and alerting new Date(2011, 9, 9) (which is a Sunday and is shown as a Saturday; there must be something strange with your settings). Of course you can't control these settings on the client.
To work around this issue, I have to know what you exactly need: if you merely want some date/time display that doesn't take timezone and DST into account, just use UTC, like:
var d = new Date(Date.UTC(2011, 9, 9));
alert(d.toUTCString()); // Shows: Sun, 9 Oct 2011 00:00:00 UTC
To show/calculate with the individual parts of the Date object, use the corresponding UTC methods.

DateJS parsing mystery

I'm using DateJS to parse user-inputted dates, and getting some strange results.
Date.parse("15 Jan 2010") returns Fri Jan 15 00:00:00 EST 2010 (right)
Date.parse("15-Apr-2010") returns Thu Apr 15 00:00:00 EDT 2010 (right)
Date.parse("15 Apr 2010") returns Thu Apr 1 00:00:00 EDT 2010 (wrong)
As far as I can tell, the d MMM yyyy input format works fine for every month except April and August; in those two cases, it returns the first of the month no matter what day is entered. Is this a bug, or is there a logical explanation I'm missing?
Aha: Looks like the version in the "Download" link is a good bit older than the current source. Here's the commit that fixed this bug:
Dan Yoder fixed bug with timeContext pattern where if a date included
"april" or "august", the parser thought the 'a' was the beginning of a time part
(as in am/pm).
The most recent version of the EN-US script is here:
http://code.google.com/p/datejs/source/browse/trunk/build/date-en-US.js
It would be nice if the website linked to this instead of to a zip file that hasn't been updated for a couple of years.

Categories