admin管理员组文章数量:1189403
First of all, I think timezone probably has something to do with this. I'm in EST/EDT. Also, I'm testing this on chromium 17 / linux.
Now, let's say I create two dates like this:
// December 5
dateFromNumbers = new Date(2020, 11, 5);
dateFromString = new Date("2020-12-5");
It seems these dates should have identical timestamps, and they do:
+dateFromNumbers == +dateFromString; // true
...at least in this case. But in some cases, they don't:
// December 15
dateFromNumbers = new Date(2020, 11, 15);
dateFromString = new Date("2020-12-15");
+dateFromNumbers == +dateFromString; // false
What's going on here?
dateFromNumbers; // Tue Dec 15 2020 00:00:00 GMT-0500 (EST)
dateFromString; // Mon Dec 14 2020 19:00:00 GMT-0500 (EST)
Looks like dateFromString
is 5 hours earlier than dateFromNumbers
in this case (EST is GMT - 5, I'm sure it's related somehow).
It seems to affect the ends of months October through December. Here's a fiddle that makes it easy to see which days differ (unless you are red-green colorblind, in that case it may be difficult to see, my apologies).
/
What gives?
Notes:
- You can set your system timezone to EST/EDT to see the jsfiddle example as I'm seeing it.
- Date's month numbers are zero-based; the
11
is not a typo. - This issue appears in every year that I checked.
First of all, I think timezone probably has something to do with this. I'm in EST/EDT. Also, I'm testing this on chromium 17 / linux.
Now, let's say I create two dates like this:
// December 5
dateFromNumbers = new Date(2020, 11, 5);
dateFromString = new Date("2020-12-5");
It seems these dates should have identical timestamps, and they do:
+dateFromNumbers == +dateFromString; // true
...at least in this case. But in some cases, they don't:
// December 15
dateFromNumbers = new Date(2020, 11, 15);
dateFromString = new Date("2020-12-15");
+dateFromNumbers == +dateFromString; // false
What's going on here?
dateFromNumbers; // Tue Dec 15 2020 00:00:00 GMT-0500 (EST)
dateFromString; // Mon Dec 14 2020 19:00:00 GMT-0500 (EST)
Looks like dateFromString
is 5 hours earlier than dateFromNumbers
in this case (EST is GMT - 5, I'm sure it's related somehow).
It seems to affect the ends of months October through December. Here's a fiddle that makes it easy to see which days differ (unless you are red-green colorblind, in that case it may be difficult to see, my apologies).
http://jsfiddle.net/9gBfX/
What gives?
Notes:
- You can set your system timezone to EST/EDT to see the jsfiddle example as I'm seeing it.
- Date's month numbers are zero-based; the
11
is not a typo. - This issue appears in every year that I checked.
- 1 In your second case date is November 15, 2020 and December 15, 2020. is it a typo ? – Habib Commented Apr 22, 2012 at 16:03
- 1 Running Chrome 18.0.1025.162 m, Windows, GMT +2: the results are reproducible. But explicitly specifying the time in the string representation solves the problem. I generally avoid dates from strings because the format support across browsers is varied and poorly documented, milliseconds are a lot more reliable. – user1233508 Commented Apr 22, 2012 at 16:23
5 Answers
Reset to default 7After looking in V8's source code:
// Specification:
// Accept ES5 ISO 8601 date-time-strings or legacy dates compatible
// with Safari.
<...>
// A string that matches both formats (e.g. 1970-01-01) will be
// parsed as an ES5 date-time string - which means it will default
// to UTC time-zone. That's unavoidable if following the ES5
// specification.
Reading the surrounding code, it seems that a date-time string with both month and day 2 symbols long is considered a valid ES5 date-time string. Further down in the ES5 parser, after it parses the dates and times, there's a comment:
// Successfully parsed ES5 Date Time String. Default to UTC if no TZ given.
In case of "YYYY-MM-DD", once the code gets that far, the ES5 parser has successfully parsed the entire string, so it returns before the legacy parser gets a chance to localize the timezone. Otherwise (month/day are one symbol long) it's treated as a "legacy" datetime and the legacy parser gets to deal with it and localize it.
Here's a simplified answer drawing from the other answers.
Date recognizes different string formats
- Nonstandard dates
- RFC 2282 dates
- ES 5 dates
Most formats are interpreted as local dates
On page 14 of RFC 2282, we see:
The date and time-of-day SHOULD express local time.
Nonstandard dates are treated in similar fashion.
ES 5 format is interpreted as UTC
In section 15.9.1.15 of the ES 5 spec we see:
The value of an absent time zone offset is “Z”.
"Z" represents UTC time.
The tenth of October
ES 5 formatted dates require double-digit months and days. The months and days in the original post are not zero-padded. "2020-9-9" is not a valid ES 5 date representation; it's a non-standard format, so it's interpreted in local time. "2020-10-10" is a valid ES 5 date representation, so it must be interpreted in UTC.
Possible workarounds
- Don't use the string constructor / Date.parse!
- Change the separator character so the format never matches the ES 5 format.
- Specify a timezone.
- Adjust dates to local time. If they have hours or minutes:
date.setMinutes(date.getTimezoneOffset());
(this seems to work, anyway).
relaying on this post, it seems that the Date
's string argument constructor is implementation sensitive, due to various Date.parse()
implementations by browsers.
your measurements are correct, and you probably should avoid using this constructor altogether, if you wish your browser to parse EST correctly.
Using "-" as a date separator for USA dates confuses some browsers, some will perform date arithmetic others will return NaN, so use the "/" date separator. A culture aware solution is to use date.js, which is an outstanding JavaScript date handler that resolves issues like the one you have pointed out (http://www.datejs.com/). Using the parse method removes all confusion:
Date.parse("2020-12-15").toString() // yields the correct date ("Tue Dec 15 00:00:00 PST 2020").
It looks like the date constructor requires spaces rather than '-'. Its the recommended way. Check out this link:
3.3. Date and Time Specification
Though foldingwhite space is permitted throughout the date-time specification, it is RECOMMENDED that a single space be used in each place that FWS appears (whether it is required or optional)
Also check out this link:
https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date
dateString: String value representing a date. The string should be in a format recognized by the parse method (IETF-compliant RFC 2822 timestamps).
I tried following code and it returns true
dateFromNumbers = new Date(2020, 11, 15);
dateFromString = new Date("2020 12 15");
alert(+dateFromNumbers == +dateFromString);
Also its not a problem start with the month of October, it has do with the double digit months. If I try the same method with September then:
dateFromNumbers = new Date(2020, 8, 15);
dateFromString = new Date("2020-09-15");
alert(+dateFromNumbers == +dateFromString); // This returns false
But if I use single digit for September then it returns true
dateFromNumbers = new Date(2020, 8, 15);
dateFromString = new Date("2020-9-15");
alert(+dateFromNumbers == +dateFromString); // This returns true
And if use space with double digit September, then it returns true
dateFromNumbers = new Date(2020, 8, 15);
dateFromString = new Date("2020 09 15");
alert(+dateFromNumbers == +dateFromString);//This returns true
本文标签:
版权声明:本文标题:javascript - Date constructor: numeric arguments vs. string argument giving different dates in some cases - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1738394125a2084410.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论