新日期(" 2017-01-01")和新日期(" 2017-1-1")之间有什么区别?

时间:2017-03-28 03:23:45

标签: javascript

我在Chrome控制台中输入new Date("2017-01-01"),输出显示其小时为8,但new Date("2017-01-1")new Date("2017-1-01")显示其小时均为0,那么new Date(dateString)如何解析?

new Date("2017-01-01")
// Sun Jan 01 2017 08:00:00 GMT+0800 (中国标准时间)*
new Date("2017-01-1")
// Sun Jan 01 2017 00:00:00 GMT+0800 (中国标准时间)*
new Date("2017-1-1")
// Sun Jan 01 2017 00:00:00 GMT+0800 (中国标准时间)*
new Date("2017-1-01")
// Sun Jan 01 2017 00:00:00 GMT+0800 (中国标准时间)*

4 个答案:

答案 0 :(得分:78)

“2017-01-01”遵循 ISO标准 ES5 Date Time String format (simplification of ISO 8601 Extended Format),因此它是UTC时间,即中国的早上8点。所有其他字符串在Chrome 1 中被解析为本地时间。

1 Chromium中的相关源代码:https://cs.chromium.org/chromium/src/v8/src/dateparser-inl.h?type=cs&l=16

Chromium中的日期解析遵循标准ES5规则以及这些额外规则:

  • 忽略第一个数字之前的任何无法识别的单词。
  • 忽略带括号的文字。
  • 后跟:的无符号数字是时间值,并添加到TimeComposer。后跟::的数字也会增加第二个零。后跟.的数字也是时间,必须后跟毫秒。任何其他数字都是日期组件,并添加到DayComposer
  • 月份名称(或实际上:与月份名称具有相同前三个字母的任何单词)将被记录为Day作曲家中的指定月份。
  • 可识别为时区的单词被记录为(+|-)(hhmm|hh:)
  • 在读取数字后(第一个数字之前,允许任何垃圾),旧版日期不允许使用额外的符号(+-)或不匹配的)。< / LI>
  • 将使用ES5规则解析满足ES5规则和上述规则的任何字符串。这意味着"1970-01-01"将处于UTC时区而不是本地时区。

这是什么意思?

首先请注意,“2017-01-01”在UTC时间解析,因为它是“日期”字符串而不是“日期时间”字符串,并且它匹配“日期”字符串的ES5定义。如果附加时间,则它将遵循ISO标准并在当地时间进行解析。

示例:

  • 2017-01-01 - 2017年1月1日UTC时间
  • 2017-01-01T00:00 - 2017年1月1日当地时间
  • 2017-1-1 - 2017年1月1日当地时间
  • 2017-(hello)01-01 - 2017年1月1日当地时间
  • may 2017-01-01 - 2017年5月1日当地时间
  • mayoooo 2017-01-01 - 2017年5月1日当地时间
  • "jan2017feb-mar01apr-may01jun" - 2017年6月1日当地时间

答案 1 :(得分:18)

  

新日期(“2017-01-01”)与新日期(“2017-1-1”)

之间的差异

new Date("2017-01-01")符合规范(详见下文)。 new Date("2017-1-1")不是,因此依赖于JavaScript引擎想要应用的任何“...特定于实现的启发式或特定于实现的日期格式”。例如,您不能保证它将如何(或是否)成功解析,如果是,它是否将被解析为UTC或当地时间。

尽管new Date("2017-01-01")符合规范,但遗憾的是浏览器应该用它来做一个移动目标,因为它上面没有时区指示符:

  • In ES5(2009年12月),没有时区指示符的字符串应该被解析为UTC。但这与ISO-8601标准的日期/时间格式不同,后者表示没有时区指示符的字符串是本地时间,而不是UTC。因此,在ES5中,new Date("2017-01-01")以UTC格式解析。
  • In ES2015(又名ES6,2015年6月),没有时区指示符的字符串应该是本地时间,而不是UTC,如ISO-8601。因此,在ES2015中,new Date("2017-01-01")被解析为本地时间。
  • ,再次更改in ES2016(2016年6月),因为浏览器多年来一直在解析日期版本,其中-为UTC。因此,从ES2016开始,仅限日期表单(如"2017-01-01")以UTC格式解析,但日期/时间表单(如"2017-01-01T00:00:00")是在当地时间解析。

可悲的是,目前并非所有JavaScript引擎都实现了规范。 Chrome(撰写本文时,v56)以UTC格式解析日期/时间表,即使它们应该是本地时间(IE9也是如此)。但Chrome,Firefox和IE11(我没有IE10或Edge方便)都正确处理仅限日期的表格(如UTC)。 IE8根本没有实现ISO-8601表格(在ES5规范发布之前已经发布)。

答案 2 :(得分:3)

解析日期时,JavaScript会将ISO日期解释为UTC时间,将其他格式解释为本地时间。

MDN article所示,

  

如果字符串仅为ISO 8601日期,则UTC时区用于解释参数。

     

给定日期字符串&#34; 2014年3月7日&#34;,parse()假设一个本地时区但是给出了ISO格式,例如&#34; 2014-03-07&#34 ;它将假定UTC的时区(ES5和ECMAScript 2015)。因此,使用这些字符串生成的Date对象可能代表不同的时刻,具体取决于ECMAScript支持的版本,除非系统设置了UTC的本地时区。 这意味着两个看似等效的日期字符串可能会导致两个不同的值,具体取决于要转换的字符串的格式。

&#13;
&#13;
// 2017-03-28 is interpreted as UTC time,
// shown as 2017-03-28 00:00:00 in UTC timezone,
// shown as 2017-03-28 06:00:00 in my timezone:
console.log("ISO dates:");
var isoDates = [new Date("2017-03-28")];
for (var dt of isoDates)
{
  console.log(dt.toUTCString() + " / " + dt.toLocaleString());
}

// Other formats are interpreted as local time, 
// shown as 2017-03-27 18:00:00 in my timezone,
// shown 2017-03-28 00:00:00 in my timezone:
console.log("Other formats:");
var otherDates = [new Date("2017-3-28"), new Date("March 28, 2017"), new Date("2017/03/28")];
for (var dt of otherDates)
{
  console.log(dt.toUTCString() + " / " + dt.toLocaleString());
}
&#13;
&#13;
&#13;

答案 3 :(得分:2)

此格式为国际标准(ISO格式)

new Date("2017-01-01")

这可以保证所有浏览器的输出相同。

但是,其他格式可能会根据浏览器的不同而改变,因为它们的定义不太明确。

你可以看到这种格式

new Date("2017-1-1")

在chrome中成功解析,但在IE 11中出错