Why these date setDate( day+1 ) not adding 24 hours? - javascript

[Please help me improve the title if it doesn't describe the question clear]
I found this weird thing when I develop a jquery plugin:
var a = new Date('1986-05-03');
a.setHours(0,0,0,0);
// a = Sat May 03 1986 00:00:00 GMT+0800 (CST)
a.setDate( a.getDate() + 1 );
// a = Sat May 03 1986 23:00:00 GMT+0800 (CST)
It actually adds 23 hours
There's some other ticket mentioned daylight savings, but May 3 is not the beginning of daylight saving days, right ?
Further, I tried to print all the not-24-hours date, here's my code:
var start = new Date('1900-01-01'); // FYI, IE8- doesn't support this kind of date construction
var end = new Date('2014-01-01');
start.setHours(0,0,0,0);
end.setHours(0,0,0,0);
while (start.getTime() < end.getTime()) {
var oneMoreDay = new Date(start.getTime());
oneMoreDay.setDate(start.getDate() + 1);
var diff = oneMoreDay.getTime() - start.getTime();
if (diff != 86400000) {
console.log(start);
}
start = oneMoreDay;
}
Here's the output:
Sat May 03 1986 23:00:00 GMT+0800 (CST) VM124:12
Fri Sep 12 1986 23:00:00 GMT+0900 (CST) VM124:12
Sat Apr 11 1987 23:00:00 GMT+0800 (CST) VM124:12
Fri Sep 11 1987 23:00:00 GMT+0900 (CST) VM124:12
Sat Apr 09 1988 23:00:00 GMT+0800 (CST) VM124:12
Fri Sep 09 1988 23:00:00 GMT+0900 (CST) VM124:12
Sat Apr 15 1989 23:00:00 GMT+0800 (CST) VM124:12
Fri Sep 15 1989 23:00:00 GMT+0900 (CST) VM124:12
Sat Apr 14 1990 23:00:00 GMT+0800 (CST) VM124:12
Fri Sep 14 1990 23:00:00 GMT+0900 (CST) VM124:12
Sat Apr 13 1991 23:00:00 GMT+0800 (CST) VM124:12
Fri Sep 13 1991 23:00:00 GMT+0900 (CST)
So, it's not in every year! Why are these date special?

It is every April/May and September and it gives you a different GMT offset. That is daylight savings.
From Wikipedia:
After the Chinese Civil War, in 1949, a unified time zone—GMT+8—was
established by the People's Republic of China for all its territories,
called Beijing Time (sometimes known as Chinese Standard Time).
Daylight saving time was observed from 1986 to 1991.
It isn't a problem. The time is correct. The time offset just changes. Ignore it, all calculation will work correctly.
P.S. That is the first time I had to research the Chinese Civil War for stack overflow.

It is two days (beginning and end) for every year that using a daylight-saving calendar in your local timezone.
Daylight saving time was observed only from 1986 to 1991 in China, so I ran the code in Chinese time zone I got the above results.
But if I change my timezone to London time, I get the different output, it's two days in almost every year, March and October.
You can run that code in different timezone to see the differences.

Related

Javascript Date() timezone incosistency

I get inconsistent timezone based on params to Date():
new Date()
Sun Oct 25 2015 18:10:42 GMT+0200 (IST)
new Date(1445720400)
Sat Jan 17 1970 19:35:20 GMT+0200 (IST)
new Date(144572040000)
Thu Aug 01 1974 09:54:00 GMT+0300 (IDT)
new Date(14457204000000)
Thu Feb 17 2428 20:00:00 GMT+0200 (IST)
I tried reading the docs or finding an explanation to this weirdness, but couldn't.
I've checked on both Chrome 46 and Safari 7.1.8,
Any ideas?
Isn't this just daylight savings? One of the dates happened to be in the summer?
The problem in then you set different time in ms as param for 'new Date()'. And you have different time zones because the Date has been generated in different seasons (Summer's time and Winter's time). It is normal.

FireFox 34 setMinutes BUG?

There is a strange behaviour of the FireFox 34 setMinutes date method to set the 60 minutes for 2008 year 01 January 23 hour 00 minutes 00 sec. It is expected that will increase day but this does not.
var initDate = [2008, 0, 1];
var d = new Date(initDate[0], initDate[1], initDate[2]);
document.body.innerHTML += d + "<br/>";
d.setHours(23);
d.setMinutes(60);
document.body.innerHTML += d + "<br/>";
The FireFox 34 result is:
Tue Jan 01 2008 00:00:00 GMT+0300 (Russia TZ 2 Standard Time)
Tue Jan 01 2008 23:00:00 GMT+0300 (Russia TZ 2 Standard Time)
instead of Chrome 39.0.2171.71 m:
Tue Jan 01 2008 00:00:00 GMT+0300 (Russia TZ 2 Standard Time)
Wed Jan 02 2008 01:00:00 GMT+0400 (Russia TZ 2 Daylight Time)
If I change the year to 2006 the result is ok:
Sun Jan 01 2006 00:00:00 GMT+0300 (Russia TZ 2 Standard Time)
Mon Jan 02 2006 00:00:00 GMT+0300 (Russia TZ 2 Standard Time)
http://jsfiddle.net/7dp8xvf8/1/
Is it a bug?
UPDATE: IE 8 and 9 has the same behaviour, but 10-11 is ok.
Given the specification, I believe that this is indeed intended behavior. In particular, notice that the MakeTime function contains no overflow checks (i.e., it does not determine whether the number of minutes is less than 60). The MakeDate function behaves similarly; hence, Firefox is actually following the specification correctly.
This works as intended for me in Firefox 39.0.3 as well as the current development build (42a), as I get:
"Tue Jan 01 2008 00:00:00 GMT+0300 (MSK)"
"Wed Jan 02 2008 00:00:00 GMT+0300 (MSK)"
This is also what the ES specification requires.
If this still does not work for you (which would be surprising), and especially if you see timezone-related weirdness, you should also mention your system TZ settings.

Date constructors provide unexpected results when called with similar arguments

I got one weird issue with Date object initialization. And wondering if someone can explain why..
var exp1 = new Date('2014-10-17');
var exp2 = new Date(2014,9,17);
var exp3 = new Date('17 Oct 2014');
console.log(exp1);
console.log(exp2);
console.log(exp3);
Results:
Thu Oct 16 2014 18:00:00 GMT-0600 (MDT) // 16th?
Fri Oct 17 2014 00:00:00 GMT-0700 (MST) // Why GMT -7
Fri Oct 17 2014 00:00:00 GMT-0600 (MDT) // The only one that works as expected
Why are these three Date objects so different?
The first date is treated as GMT since no time zone offset is provided. When logged out it shows the time in your local timezone. Adding an offset (exp4 below), I get the date expected.
var exp1 = new Date('2014-10-17');
var exp2 = new Date(2014,9,17);
var exp3 = new Date('17 Oct 2014');
var exp4 = new Date('2014-10-17z-0500');
Results:
Thu Oct 16 2014 19:00:00 GMT-0500 (Central Daylight Time)
Fri Oct 17 2014 00:00:00 GMT-0500 (Central Daylight Time)
Fri Oct 17 2014 00:00:00 GMT-0500 (Central Daylight Time)
Fri Oct 17 2014 00:00:00 GMT-0500 (Central Daylight Time)
I am not sure about exp2 for you, but suspect it has something to do with daylight savings time and that you live in an area that does not observe daylight savings (Arizona?).
Edit: this seems to be browser specific. The results above were generated in Chrome while in IE 11, exp4 was an invalid date. For IE 11 I had to use this format:
var exp4 = new Date('2014-10-17T00:00-05:00');

Is it a bug that javascript doesn't handle days that were skipped for historic reasons?

Some on here may know this, some may not. The date of Sept 3, 1752 doesn't exist. You can check this out for yourself at a number of places such as this one.
I was interested in how javascript and the Date() function would handle this, so I tried the following code:
var sept2 = new Date(1752, 8, 2);
var next = new Date(sept2);
next.setDate(sept2.getDate() + 1);
console.log(sept2, next);
I was suprised to see the results:
Date {Sat Sep 02 1752 00:00:00 GMT-0400 (Eastern Standard Time)}
Date {Sun Sep 03 1752 00:00:00 GMT-0400 (Eastern Standard Time)}
There are two errors here:
the 3rd didn't exist.
The 2nd should be a Wednesday. It's NOT on a Saturday.
So...are these two issues bugs in Date()?
In the British speaking parts of the world, there were no dates between September 2 and the 14th. You went to bed on the second and woke up on the 14th. For much of the rest of the European world, the change happened on October 4, 1582. The next date was October 15, the first day of the Gregorian calendar. Calculating Dates before 1970, be sure you know what calendar you are using.
There's no handling of the transition from Julian to Gregorian calender, so your observation is right.
The 2nd bug is caused because date in javascript are calculated from January 1st, 1970.
You can easily test it by looking at september 14, 1952 day (Tuesday) which is right.
Thu Sep 14 1752 00:00:00 GMT-0400 (Est) <- ok
Wed Sep 13 1752 00:00:00 GMT-0400 (Est) <- did not happen
Tue Sep 12 1752 00:00:00 GMT-0400 (Est)
Mon Sep 11 1752 00:00:00 GMT-0400 (Est)
Sun Sep 10 1752 00:00:00 GMT-0400 (Est)
Sat Sep 09 1752 00:00:00 GMT-0400 (Est)
Fri Sep 08 1752 00:00:00 GMT-0400 (Est)
Thu Sep 07 1752 00:00:00 GMT-0400 (Est)
Wed Sep 06 1752 00:00:00 GMT-0400 (Est)
Tue Sep 05 1752 00:00:00 GMT-0400 (Est)
Mon Sep 04 1752 00:00:00 GMT-0400 (Est)
Sun Sep 03 1752 00:00:00 GMT-0400 (Est)
Sat Sep 02 1752 00:00:00 GMT-0400 (Est) <- did happen, but wrong day of week.
Fri Sep 01 1752 00:00:00 GMT-0400 (Est) <- same
I suppose that every date before september 14, 1752 will have a wrong day of the week.

Parse String Dates with different timezones

I am trying to be able to take many strings with many different formats and in different timezones and turn them into either UTC or my localtime. I have tried the following and for some reason it has given me a hour off:
var moment = require('moment');
console.log(moment('Mon, 30 Sep 2013 18:00:00 EST').format()); //2013-09-30T16:00:00-07:00
console.log(new Date('Mon, 30 Sep 2013 18:00:00 EST')); //Mon Sep 30 2013 16:00:00 GMT-0700 (PDT)
console.log(new Date()); //Mon Sep 30 2013 15:00:00 GMT-0700 (PDT)
The only thing I can think of that could cause this is day light savings time but I am not sure. Any suggestions with how to proceed?
You used the wrong time zone. For an apples-to-apples comparison, use EDT (eastern daylight time):
> console.log(new Date('Mon, 30 Sep 2013 18:00:00 EDT'));
Mon Sep 30 2013 15:00:00 GMT-0700 (PDT)
which is what you would expect (3 hour difference)

Categories

Resources