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

hiw*_*way 74 javascript

我输入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 (??????)*
Run Code Online (Sandbox Code Playgroud)

Der*_*會功夫 78

"2017-01-01"遵循ISO标准 ES5日期时间字符串格式(ISO 8601扩展格式的简化),因此它是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:).
  • 传统日期不允许在读取数字后添加额外的符号(+-)或不匹配)(在第一个数字之前,允许任何垃圾).
  • 任何满足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日当地时间

  • *"所有其他字符串都被解析为本地时间."*不一定.一旦你没有解析规范中唯一的日期/时间格式,你将进入*"特定于实现的启发式或特定于实现的日期格式"*并且所有的赌注都已关闭. (9认同)
  • @KeyWeeUsr你是说你在"2016-12-31"得到了不同的结果?对我来说,一个人也解析为ISO. (4认同)
  • "标准ES5规则",虽然如此,可能是我今天读到的最奇怪的命题. (4认同)
  • @TJCrowder添加了"在Chrome中"的准确性. (2认同)
  • @KeyWeeUsr:格式要求年份为四位数,月份和日期为两位数.当然它处理2016-12-31.它不会处理的是2016-2-28. (2认同)

T.J*_*der 18

新日期("2017-01-01")与新日期("2017-1-1")之间的差异

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

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

  • 在ES5(2009年12月)中,没有时区指示符的字符串应该被解析为UTC.但这与ISO-8601标准的日期/时间格式不同,后者表示没有时区指示符的字符串是本地时间,而不是UTC.所以在ES5中,new Date("2017-01-01")用UTC解析.
  • 在ES2015(又名ES6,2015年6月)中,没有时区指示符的字符串应该是本地时间,而不是UTC,如ISO-8601.所以在ES2015中,new Date("2017-01-01")被解析为本地时间.
  • 但是,这在ES2016(2016年6月)中再次发生了变化,因为浏览器多年来一直在解析仅限日期的表格-.因此,从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规范发布之前已经发布).

  • 我想故事的寓意是,不要使用Date构造函数解析字符串. (12认同)