为什么第一个输入正常工作,但第二个输入在5小时前给出了一个结果?
new Date("2000-1-1")
Sat Jan 01 2000 00:00:00 GMT-0500 (EST)
new Date("2000-01-01")
Fri Dec 31 1999 19:00:00 GMT-0500 (EST)
我怎样才能让第二个与我合作?
var a = new Date("2000-1-1"); // Sat Jan 01 2000 00:00:00 GMT-0500 (EST)
var b = new Date("2000-01-01"); // Fri Dec 31 1999 19:00:00 GMT-0500 (EST)
console.log(a, a.getTime());
console.log(b, b.getTime());

答案 0 :(得分:2)
MDN 的Date.parse()
页面实际上描述了您看到这一点的原因(其中有许多正式支持的详细信息Date
描述参数格式)。具体做法是:
假定时区的差异
如果日期字符串为“2014年3月7日”,则parse()会假定为本地时区,但如果采用ISO格式(如“2014-03-07”),则会假定UTC时区(ES5和ECMAScript) 2015年)。因此,使用这些字符串生成的Date对象可能代表不同的时刻,具体取决于ECMAScript支持的版本,除非系统设置了UTC的本地时区。这意味着两个看似等效的日期字符串可能会导致两个不同的值,具体取决于要转换的字符串的格式。
所以你所看到的是两件事的组合:
因此,您将看到2000年1月1日(UTC时间)(或1999年12月31日晚上7点)午夜的美国东部时区版本。
由于你的第一个例子是使用非标准格式(来自JS的观点),所以第一个假设没有发挥作用,并且假设值的本地时区(特定于浏览器)创建值关于如何处理非标准格式的决定。)
答案 1 :(得分:0)
黄金法则永远不会使用Date构造函数或Date.parse解析字符串,因为它们在很大程度上依赖于实现。有许多怪癖。
根据ECMA-262,字符串" 2000-01-01"应该被解析为有效的ISO 8601仅限日期的表单but for timezone UTC+0000。像IE 8这样的旧浏览器可能根本不会解析它,有些可能会将其视为本地浏览器。
字符串" 2000-1-1"不是ISO 8601格式,因此浏览器可能会回归到他们喜欢的任何启发式,包括:
目前的浏览器中至少有1个和2个。
因此,最好的办法是使用带解析器的库并提供字符串的格式,或者如果只有一种格式要处理,则编写一个简单的函数,例如
/* Parse ISO 8601 date only form as local
** @param {string} s - string in format YYYY-M[M]-D[D]
** @returns {Date} If date parts out of range, returns invalid date
*/
function parseISOLocal(s) {
var b = s.split(/\D/);
var d = new Date(b[0], --b[1], b[2]);
return isNaN(d) || d.getMonth() != b[1]? new Date(NaN) : d;
}
['2000-1-1','2000-01-01','2000-2-29','1900-2-29'].forEach(function(s) {
console.log(s + ' : ' + parseISOLocal(s).toString());
});