代码:
var x = new Date(Date.UTC(0, 0, 0));
x.setUTCFullYear(0);
// in Firefox, writes "Date {Sat Dec 30 0000 16:00:00 GMT-0800 (Pacific Standard Time)}"
// in IE, writes "LOG: Sat Dec 30 16:00:00 PST 1 B.C."
console.log(x);
// Create a copy of x
var y = new Date(x);
// in Firefox, writes "Date {Sat Dec 30 0000 16:00:00 GMT-0800 (Pacific Standard Time)}"
// in IE, writes "LOG: Invalid Date"
console.log(y);
这似乎适用于任何非常古老的日期
我的问题:这里究竟什么是无效的,为什么只有IE?如何解决此问题并实际创建日期副本?
答案 0 :(得分:6)
似乎当一个日期对象被传递给IE中的Date构造函数时,它被评估为时间值以外的东西(可能调用toString
)。
要强制它评估时间值,您可以执行以下操作:
new Date(x.getTime());
或
new Date(+x);
或任何使日期返回其时间值而不是字符串的表达式。
当单个值传递给Date constructor时,它会转换为基元。规范没有说明是否应该将其转换为字符串或数字。所以IE不是不合规的,它只是表现不同。
虽然IE在这种情况下似乎没有正确解析它自己的日期字符串表示,但这是不寻常的。它似乎在70-01-01之前的任何日期都失败了,这可能没有实际意义,因为公历只在1582年引入。时间价值本身可以涵盖从公元前283458年到公元287396年的日期。
无论如何,修复很简单。
在ES5中,将Date传递给名为 Date.prototype.toString 的Date构造函数,以便构造函数必须解析它自己的日期字符串版本。 ECMAScript 2015已修复此问题,因此直接使用时间值。
然而,并非所有浏览器都支持ECMAScript 2015,所以尽管new Date(date)
返回错误值的可能性很小并且日渐变小,但使用+date
仍然更安全(直到IE 8)完全没了了。)