复制非常旧的日期时,IE中的日期"无效日期"

Kre*_*ase 0 javascript date

码:

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

这似乎发生在任何非常古老的日期

我的问题:这里究竟什么是无效的,为什么只有IE?如何解决此问题并实际创建日期副本?

Rob*_*obG 6

似乎当一个日期对象被传递给IE中的Date构造函数时,它被评估为除时间值之外的其他东西(可能是调用toString).

要强制它评估时间值,您可以执行以下操作:

new Date(x.getTime());
Run Code Online (Sandbox Code Playgroud)

要么

new Date(+x);
Run Code Online (Sandbox Code Playgroud)

或任何使日期返回其时间值而不是字符串的表达式.

将单个值传递给Date构造函数时,它将转换为基元.规范没有说明是否应该将其转换为字符串或数字.所以IE不是不合规的,它只是表现不同.

虽然IE在这种情况下似乎没有正确解析它自己的日期字符串表示,但这是不寻常的.它似乎在70-01-01之前的任何日期都失败了,这可能没有实际意义,因为公历只在1582年引入.时间价值本身可以涵盖从公元前283458到公元287396的日期.

无论如何,修复很简单.

编辑2016

ES5中,将Date传递给Date构造函数,名为Date.prototype.toString,因此构造函数必须解析它自己的日期字符串版本.ECMAScript 2015修复了这个问题,因此直接使用时间值.

但是,并非所有浏览器都支持ECMAScript 2015,所以即使new Date(date)返回错误值的机会很小并且日渐变小,它仍然更安全+date(直到IE 8完全消失).