Javascript 为什么不是';";2016年2月16日;等于;2016-02-16 00:00“吗;?
我试图将这两个日期字符串传递给Javascript 为什么不是';";2016年2月16日;等于;2016-02-16 00:00“吗;?,javascript,date,datetime,Javascript,Date,Datetime,我试图将这两个日期字符串传递给新日期(t) 我希望两个字符串都代表同一个时间,毕竟,如果我省略了时间,它不应该是那天的午夜吗 但是, new Date("2016-02-16 00:00") 按预期返回2016年2月16日当地时间午夜 new Date("2016-02-16") 返回2016-02-16,午夜UTC,这是错误的,或者至少不是我所期望的,因为另一个字符串解析为 如果它们都有相同的行为,无论是将时间返回为本地时间还是UTC,我都能理解,但它们为什么返回这样不同的东西,这似乎很不
新日期(t)
我希望两个字符串都代表同一个时间,毕竟,如果我省略了时间,它不应该是那天的午夜吗
但是,
new Date("2016-02-16 00:00")
按预期返回2016年2月16日当地时间午夜
new Date("2016-02-16")
返回2016-02-16,午夜UTC,这是错误的,或者至少不是我所期望的,因为另一个字符串解析为
如果它们都有相同的行为,无论是将时间返回为本地时间还是UTC,我都能理解,但它们为什么返回这样不同的东西,这似乎很不一致
作为一种解决方法,每当我遇到一个没有相应时间戳的日期时,我可以附加“00:00”以获得一致的行为,但这似乎是相当脆弱的
我从一个输入元素获得这个值,类型为“datetime local”,因此我必须处理page元素返回的值,这似乎特别不一致
我是做错了什么,还是应该做些不同的事情
返回2016-02-16,午夜UTC,这是错误的,或者至少不是我所期望的,因为另一个字符串解析为
它将时区偏移量添加到00:00
新日期(“2016-02-16”)
输出2016年2月16日星期二05:30:00 GMT+0530(印度标准时间)
我的时区以偏移值(以分钟为单位)+330
,因此它将330分钟增加到00:00
依照
如果ToString导致突然完成,则完成记录为
他立刻回来了。否则,parse将解释结果字符串
作为日期和时间;它返回一个数字,即UTC时间值
对应于日期和时间。该字符串可以解释为
本地时间、UTC时间或其他时区的时间,具体取决于
关于字符串的内容
当您显式地设置时间单位时(“2016-02-16 00:00”)将使用设置为小时和分钟
否则如第2节所述
如果没有时区偏移,则日期时间将被解释为
当地时间
您可能遇到了ES5、ES6实现与预期结果之间的差异。根据at MDN,“特别是在不同的ECMAScript实现中,如“2015-10-12 12:00:00”字符串可能被解析为NaN、UTC或本地时区”,这一点非常重要 Firefox 44和IE 11中的附加测试显示,它们都为
新日期(“2016-02-16 00:00”)
返回一个日期对象,该对象在尝试获取日期组件值时返回NaN,其toString值为
“无效日期”(不是“NaN”)。因此,在不同的浏览器中添加“00:00以获得一致的行为”很容易中断
如其他答案中所述,新日期(“2016-02-16”)默认使用零时区偏移,产生午夜UTC而非本地UTC 这是他们说的:
缺少时区偏移的值为“Z”
它还说:
函数首先尝试根据日期时间字符串格式(15.9.1.15)中调用的规则解析字符串的格式。如果字符串不符合该格式,函数可能会退回到任何特定于实现的启发式或特定于实现的日期格式
由于格式要求在日期和时间之间使用T
分隔符,因此有效时间为UTC:
> new Date("2016-02-16T00:00:00")
Tue Feb 16 2016 01:00:00 GMT+0100 (CET)
> new Date("2016-02-16")
Tue Feb 16 2016 01:00:00 GMT+0100 (CET)
…在node.js中,无效时间(不带T分隔符)似乎会转到特定于实现的localtime:
> new Date("2016-02-16 00:00:00")
Tue Feb 16 2016 00:00:00 GMT+0100 (CET)
请注意,ES6改变了这一点,同时也改变为:
如果没有时区偏移,则将日期时间解释为本地时间
生活的乐趣
编辑
根据,本规范旨在解释为没有时区的日期和时间字符串(如“2016-02-16T00:00:00”)被视为本地(根据ISO 8601),但仅日期字符串(如“2016-02-16”)被视为UTC(与ISO 8601不一致)。根据Chrome的V8源代码
ES5 ISO 8601日期:
[('-'|'+')yy]yyy[-MM[-DD]][THH:MM[:ss[.sss]][Z |(+|-)hh:MM]
后跟“:”的无符号数字是时间值,并添加到TimeComposer
如果缺少时区,则默认为Z
匹配这两种格式的字符串(例如1970-01-01
)将被解析为ES5日期时间字符串-这意味着它将默认为UTC时区
e。如果遵循ES5规范,这是不可避免的
根据报告:
函数首先尝试解析字符串的格式
根据日期时间字符串格式中调用的规则
(15.9.1.15). 如果字符串不符合该格式,则
函数可以回退到任何特定于实现的启发式或
具体实施日期格式
并接受2016-02-16
作为有效日期
此格式包括仅限日期的表格:
YYYYYYYY-MM
YYYY-MM-DD […]如果HH、mm或ss字段不存在,则使用“00”作为值 缺少的sss字段的值为“000”。缺席的价值 时区偏移量为“Z” 因此,
2016-02-16
转化为2016-02-16T00:00:00.000Z
另一个日期
2016-02-16 00:00
不符合格式,因此其解析是特定于实现的。显然,此类日期被视为具有本地时区,并且示例日期将根据时区返回不同的值:
/* tz = +05:00 */ new Date("2016-02-16 00:00").toISOString() // 2016-02-15T19:00:00.000Z
/* tz = -08:00 */ new Date("2016-02-16 00:00").toISOString() // 2016-02-16T08:00:00.000Z
总结:
- 对于一致的日期-时间格式,行为定义良好-在没有时区偏移的情况下,日期字符串被视为UTC(ES5)或本地(ES6)
- 对于不一致的日期时间格式,行为是特定于实现的-在
> new Date("2016-02-16") Tue Feb 16 2016 08:00:00 GMT+0800 (China Standard Time)
/* tz = +05:00 */ new Date("2016-02-16 00:00").toISOString() // 2016-02-15T19:00:00.000Z /* tz = -08:00 */ new Date("2016-02-16 00:00").toISOString() // 2016-02-16T08:00:00.000Z