日期构造函数:数字参数与字符串参数在某些情况下给出不同的日期 [英] Date constructor: numeric arguments vs. string argument giving different dates in some cases
问题描述
首先,我认为时区可能与这有关。我在EST / EDT。
现在,我们创建两个日期:
// 12月5日
dateFromNumbers = new Date(2020,11,5);
dateFromString = new Date(2020-12-5);
看起来这些日期应该有相同的时间戳,并且它们:
+ dateFromNumbers == + dateFromString; // true
...至少在这种情况下。但在某些情况下,它们不会:
// 12月15日
dateFromNumbers = (2020,11,15);
dateFromString = new Date(2020-12-15);
+ dateFromNumbers == + dateFromString; // false
这是怎么回事?
dateFromNumbers; // Tue Dec 15 2020 00:00:00 GMT-0500(EST)
dateFromString; // Mon Dec 14 2020 19:00:00 GMT-0500(EST)
看起来像 dateFromString
比 dateFromNumbers
早5小时(EST是GMT - 5,我确定它是相关的)。
这似乎影响了10月至12月的月底。这是一个小提琴,它使得很容易看到哪些天不同(除非你是红绿色的颜色,在这种情况下可能很难看到,我的道歉)。
有什么优点? / p>
注意:
- 可以将系统时区设置为EST / EDT,以查看jsfiddle示例,因为我看到它。
- 日期的月份数基于零; 不是打字错误。
- 这个问题出现在我检查的每一年。
查看 V8的源代码:
//规格:
//使用Safari接受ES5 ISO 8601日期时间字符串或旧日期兼容
//。
< ...>
//匹配这两种格式的字符串(例如1970-01-01)将是
//解析为ES5日期时间字符串 - 这意味着它将默认
//到UTC时区。如果遵循ES5
//规范,这是不可避免的。
读取周围的代码,看起来是一个日期 - 时间字符串,包含月份和日期2个符号被认为是有效的ES5日期时间字符串。在ES5解析器中,在解析日期和时间之后,有一个注释:
//成功解析ES5日期时间串。默认为UTC,如果没有给定TZ。
在YYYY-MM-DD的情况下,一旦代码到达远处,ES5解析器已成功解析整个字符串,因此它在旧解析器获得本地化时区的机会之前返回。否则(月/日为一个符号长),它被视为遗留日期时间,旧的解析器将处理它并将其本地化。
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.
After 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.
这篇关于日期构造函数:数字参数与字符串参数在某些情况下给出不同的日期的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!