Javascript parse(0)返回2000年午夜,为什么?

Javascript parse(0)返回2000年午夜,为什么?,javascript,v8,Javascript,V8,当我尝试Date.parse()一个整数或字符串0时,它返回946681200000,转换为以下日期: 2000年1月1日星期六00:00:00 GMT+0100(CET) 为什么? 我假设解析器将单个零解释为2000年,但是规范没有说明单字符年份定义——两者都要求字符串中包含四个字符的年份 我想更好地理解字符串“0”是如何解析为日期的,为什么它被接受为有效日期(不应该是NaN或类似的日期?),以及为什么选择2000年而不是1900年 更新 经过一些尝试和错误后,我发现在不同的数字范围内,单个数

当我尝试
Date.parse()
一个整数或字符串
0
时,它返回946681200000,转换为以下日期:

2000年1月1日星期六00:00:00 GMT+0100(CET)

为什么? 我假设解析器将单个零解释为2000年,但是规范没有说明单字符年份定义——两者都要求字符串中包含四个字符的年份

我想更好地理解字符串“0”是如何解析为日期的,为什么它被接受为有效日期(不应该是
NaN
或类似的日期?),以及为什么选择2000年而不是1900年

更新

经过一些尝试和错误后,我发现在不同的数字范围内,单个数字的解释实际上是不同的

  • 0-12:2000年的一个月
  • 13-31:
    NaN
  • 32-49:A year+2000,所有其他值都设置为默认值
  • 50-99:A year+1950,所有其他值都设置为默认值
  • 100-??:一年,所有其他值设置为默认值
规范中没有提到单字符年份定义

说:

如果字符串不符合要求,函数可能会退回到任何特定于实现的启发式或特定于实现的日期格式


特别是对于V8,请参见使用单个数字调用时的不可预测结果。您也可以直接读取源代码(,)。

正如Bergi正确指出的那样,规范让实现返回一个日期,而该日期不是标准格式之一

以下是它如何在Chromium的V8发动机中实现的:

if (!is_iso_date_) {
if (Between(year, 0, 49)) year += 2000;
else if (Between(year, 50, 99)) year += 1900;
}
在Chrome上
41.0.2272.76

Date.parse(0)
返回
946665000000
,即
Sat Jan 01 2000 00:00:00

Date.parse(49)
返回
2493052200000
,即
Fri Jan 01 2049 00:00:00

Date.parse(50)
返回
-631171800000
,即
Sun Jan 01 1950 00:00:00

(转换的时间为
GMT+5.30
;毫秒值将根据您的时区而变化)


Firefox在所有这些情况下都返回
NaN

有趣的是,
1
是2001年1月1日,而
2
是2011年2月1日并且通常不是我使用的强类型语言
var zeroParsed_string=Date.parse('0');var zeropassed_int=Date.parse(0);警报('string:'+zeropassessed\u string+'-int:'+zeropassessed\u int)
来查看发生了什么,它在两种情况下都返回
NaN
(在FireFox上运行)。@scimonester实际上是2001年2月1日。我想这只是一个打字错误,所以我在这里只是为了将来的读者提一下。你为什么关心返回值?垃圾进来,垃圾出去。期间–所有数字必须以10为基数。如果MM或DD字段不存在,则使用“01”作为值。如果HH、mm或ss字段不存在,则使用“00”作为值,不存在的sss字段的值为“000”。缺少的时区偏移量的值是“Z”。@KrzysztofSafjanowski:那又怎样?那么–@Bergi–规范解释了如何将0扩展到多个零,您可以根据前面的注释扩展您的答案,或者只需链接到specification@KrzysztofSafjanowski:但由于输入的格式不是
YYYY
,因此“MM/DD/HH/MM/ss missing”内容不适用。这并不能完全解决试图解析单个数字的问题-请参阅问题中添加的示例。