Date 对象基于时间值,即自 1970 年 1 月 1 日 UTC 以来的毫秒数,并具有以下构造函数
new Date();
new Date(value);
new Date(dateString);
new Date(year, month[, day[, hour[, minutes[, seconds[, milliseconds]]]]]);
来自docs,
new Date(dateString) 中的 dateString 是表示日期的字符串值。字符串应该在
由 Date.parse() 方法识别的格式(符合 IETF 的 RFC 2822
时间戳以及ISO8601的一个版本)。
现在查看 date.js 中的v8 sourcecode:
function DateConstructor(year, month, date, hours, minutes, seconds, ms) {
if (!%_IsConstructCall()) {
// ECMA 262 - 15.9.2
return (new $Date()).toString();
}
// ECMA 262 - 15.9.3
var argc = %_ArgumentsLength();
var value;
if (argc == 0) {
value = %DateCurrentTime();
SET_UTC_DATE_VALUE(this, value);
} else if (argc == 1) {
if (IS_NUMBER(year)) {
value = year;
} else if (IS_STRING(year)) {
// Probe the Date cache. If we already have a time value for the
// given time, we re-use that instead of parsing the string again.
var cache = Date_cache;
if (cache.string === year) {
value = cache.time;
} else {
value = DateParse(year); <- DOES NOT RETURN NaN
if (!NUMBER_IS_NAN(value)) {
cache.time = value;
cache.string = year;
}
}
}
...
看起来DateParse() 没有为'asd qw 101' 之类的字符串返回NaN,因此出现错误。您可以在 Chrome(v8) [返回 -58979943000000] 和 Gecko (Firefox) [返回 NaN] 中对 Date.parse('asd qw 101') 进行交叉检查。 Sat Jan 01 101 00:00:00 在您播种 new Date() 时出现,时间戳为 -58979943000000(在两个浏览器中)
对于损坏的 v8 日期解析器是否有任何解决方法?
我不会说 V8 日期解析器坏了。它只是试图以最好的方式满足RFC 2822 standard 的字符串,但壁虎也是如此,并且在某些情况下 break 给出不同的结果。
尝试 new Date('Sun Ma 10 2015') 在 Chrome(V8) 和 Firefox(Gecko) 中查看另一个此类异常。
这里 chrome 无法确定天气 'Ma' 代表 'March' 或 'May' 并给出 Invalid Date 而 Firefox 没有。
解决方法:
您可以围绕Date() 创建自己的包装器来过滤V8 自己的解析器无法过滤的那些字符串。但是,对 ECMA-5 中的内置子类化是不可行的。在 ECMA-6 中,可以对内置构造函数(数组、日期和错误)进行子类化 - reference
但是,您可以使用更强大的正则表达式来根据 RFC 2822/ISO 8601
验证字符串
^(?:(?:31(\/|-|\. |\s)(?:0?[13578]|1[02]|(?:Jan|Mar|May|Jul|Aug|Oct|Dec)))\1|(?:(?:29|30)(\/|-|\.|\s)(?:0?[1,3-9]|1[0-2]|(?:Jan|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec))\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:29(\/|-|\.|\s)(?:0?2|(?:Feb))\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0?[1-9]|1\d|2[0-8])(\/|-|\.|\s)(?:(?:0?[1-9]|(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep))|(?:1[0-2]|(?:Oct|Nov|Dec)))\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$
图片由debuggex生成
所以,看起来 v8 并没有损坏,只是工作方式不同。
希望对你有帮助!