与date(2015-01-01)不同的date('2015-1-1')输出

我刚刚发现,如果我使用new Date('2015-1-1') ,时间不是时区效应,但如果我使用new Date('2015-01-01')时间在Node.js中有时区效应。

我输出4 Date()

  console.log(new Date('2015-1-1')); console.log(new Date('2015-01-1')); console.log(new Date('2015-1-01')); console.log(new Date('2015-01-01')); 

输出是

 Thu Jan 01 2015 00:00:00 GMT+0800 (CST) Thu Jan 01 2015 00:00:00 GMT+0800 (CST) Thu Jan 01 2015 00:00:00 GMT+0800 (CST) Thu Jan 01 2015 08:00:00 GMT+0800 (CST) 

你可以看到上次是08:00:00因为我在+8时区。

我认为输出取决于月份或date的数字。 当它是10,11或12时,输出始终是08:00:00

我想知道为什么,如果有更好的办法来处理这个,除了手动检查月份和date位数?

直到并包括ECMA-262 ed 3,parsingdatestring完全取决于实现。 使用ES5时,不带时区的ISO 8601格式string被parsing为UTC,但parsing任何其他types的datestring仍然依赖于实现。

使用ECMAScript 2015,没有时区的string将被parsing为本地(即基于系统设置的偏移量)。

所以看起来你的Node.js实现不会将前3个string识别为ISO 8601,因此根据其他内部逻辑将它们parsing为UTC。

最后一个string被视为符合ISO 8601标准,因此被parsing为本地。

如果你想把所有这样的stringparsing成本地的,你可以使用一个简单的函数:

 /* @param {string} s - date string in format yyyy-[m]m-[d]d ** @returns {Date} - a Date object for the specified date in a ** timezone based on system settings. ** Assumes that the string is a valid date. */ function parseISOLocal (s) { var b = s.split(/\D/); return new Date(b[0], b[1]-1, b[2]); } document.write(parseISOLocal('2015-1-1')) 

可能是一个bug,你可以做的最好的就是使用像Moment这样的库,

 moment('2015-1-1').toString() moment('2015-1-01').toString() moment('2015-01-1').toString() moment('2015-01-01').toString() 

打印:

 "Thu Jan 01 2015 00:00:00 GMT+0100" "Thu Jan 01 2015 00:00:00 GMT+0100" "Thu Jan 01 2015 00:00:00 GMT+0100" "Thu Jan 01 2015 00:00:00 GMT+0100"