new Date(Date.parse("Jul 8, 2005"));
Fri Jul 08 2005 00:00:00 GMT-0700 (PST)
new Date(Date.parse("2005-07-08"));
Thu Jul 07 2005 17:00:00 GMT-0700 (PST)
为什么第二个解析是不正确的?
在第5版规范出来之前,Date.parse
方法完全取决于实现(new Date(string)
等同于Date.parse(string)
,只是后者返回一个数字而不是一个Date
)。在第五版规范中,增加了支持简化的(略微不正确) ISO-8601的要求(也见什么是JavaScript中有效的日期时间字符串?)。但是除此之外,没有要求Date.parse
/new Date(string)
应该接受什么,只是说他们必须接受任何Date#toString*的输出(没有说是什么)。
从ECMAScript 2017(第8版)开始,要求实现者对Date#toString和Date#toUTCString的输出进行解析,但没有规定这些字符串的格式。
从ECMAScript 2019(第9版)开始,Date#toString和Date#toUTCString的格式被指定为(分别)。
提供了另外两种格式,Date.parse应该在新的实现中可靠地解析这些格式(注意,支持并不是无处不在的,不符合要求的实现仍将使用一段时间)。
我建议手动解析日期字符串,并使用带有年、月、日参数的Date构造函数,以避免歧义。
// parse a date in yyyy-mm-dd format
function parseDate(input) {
var parts = input.split('-');
// new Date(year, month [, day [, hours[, minutes[, seconds[, ms]]]]])
return new Date(parts[0], parts[1]-1, parts[2]); // Note: months are 0-based
}
这是有方法的。一般来说,如果浏览器能够将一个日期解释为ISO-8601,它就会这样做。"2005-07-08"属于这个阵营,所以它被解析为UTC。
参见JavaScript和日期,真是一团糟!以了解更多。
虽然CMS是正确的,在解析方法中传递字符串通常是不安全的,但新的ECMA-262第五版(又称ES5)规范在15.9.4.2节中建议Date.parse()
实际上应该处理ISO格式的日期。 旧的规范则没有这样的要求。 当然,旧的浏览器和一些当前的浏览器仍然没有提供这种ES5功能。
你的第二个例子并没有错。 正如Date.prototype.toISOString()
所暗示的,它是以UTC为单位的指定日期,但以你的本地时区表示。