日期构造函数:数字参数与字符串参数在某些情况下给出不同的日期

Dag*_*bit 18 javascript constructor date

首先,我认为时区可能与此有关.我在EST/EDT.另外,我正在使用chrome 17/linux进行测试.

现在,假设我创建了两个这样的日期:

// December 5

dateFromNumbers = new Date(2020, 11, 5);
dateFromString = new Date("2020-12-5");
Run Code Online (Sandbox Code Playgroud)

看来这些日期应该具有相同的时间戳,它们会:

+dateFromNumbers == +dateFromString; // true
Run Code Online (Sandbox Code Playgroud)

......至少在这种情况下.但在某些情况下,它们不会:

// December 15

dateFromNumbers = new Date(2020, 11, 15);
dateFromString = new Date("2020-12-15");

+dateFromNumbers == +dateFromString; // false
Run Code Online (Sandbox Code Playgroud)

这里发生了什么?

dateFromNumbers; // Tue Dec 15 2020 00:00:00 GMT-0500 (EST)
dateFromString;  // Mon Dec 14 2020 19:00:00 GMT-0500 (EST)
Run Code Online (Sandbox Code Playgroud)

看起来dateFromStringdateFromNumbers在这种情况下提前5小时(EST是格林尼治标准时间 - 5,我确定它与某种方式相关).

这似乎影响了10月到12月的月末.这是一个小提琴,可以很容易地看出哪些日子不同(除非你是红绿色盲,在这种情况下可能很难看到,我的道歉).

http://jsfiddle.net/9gBfX/

是什么赋予了?


笔记:

  • 您可以将系统时区设置为EST/EDT,以便在我看到它时查看jsfiddle示例.
  • 日期的月份数量从零开始; 这11不是一个错字.
  • 这个问题出现在我检查过的每一年.

DCo*_*der 6

查看V8的源代码后:

// 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.
Run Code Online (Sandbox Code Playgroud)

读取周围的代码,似乎长度为月和日2符号的日期时间字符串被视为有效的ES5日期时间字符串.在ES5解析器中,在解析日期和时间之后,还有一个注释:

// Successfully parsed ES5 Date Time String. Default to UTC if no TZ given.
Run Code Online (Sandbox Code Playgroud)

在"YYYY-MM-DD"的情况下,一旦代码到达那么远,ES5解析器已成功解析整个字符串,因此它在遗留解析器有机会本地化时区之前返回.否则(月/日是一个符号长)它被视为"遗留"日期时间,遗留解析器可以处理它并本地化它.