Javascript 从字符串创建日期

Javascript 从字符串创建日期,javascript,date,Javascript,Date,我有两个字符串2017-03-15(date)和12:26(time)。我想从中创建一个本地化的日期对象,而不使用库 请记住,现在这里是:2017年3月14日星期二12:26:33 GMT+0800(AWST),如果我这样做: new Date( date + 'T' + time ) 我得到了错误的结果,因为日期被视为UTC: Wed Mar 15 2017 20:26:00 GMT+0800 (AWST) 如果我使用空格: new Date( date + ' ' + time ) 结

我有两个字符串
2017-03-15
date
)和
12:26
time
)。我想从中创建一个本地化的日期对象,而不使用库

请记住,现在这里是:
2017年3月14日星期二12:26:33 GMT+0800(AWST)
,如果我这样做:

new Date( date + 'T' + time )
我得到了错误的结果,因为日期被视为UTC:

Wed Mar 15 2017 20:26:00 GMT+0800 (AWST)
如果我使用空格:

new Date( date + ' ' + time )
结果是正确的:

Wed Mar 15 2017 12:26:00 GMT+0800 (AWST)
但是,这在Safari上不起作用(没有T)。Safari实际上会抛出一个错误(!)

我意识到将字符串解析为日期取决于实现。因此,唯一“正确”的方法是:

var timeSplit = time.split(':');
var dateSplit = date.split('-');

new Date( dateSplit[0], dateSplit[1] - 1, dateSplit[2], timeSplit[ 0 ], timeSplit[ 1 ] )
但它只是。所以丑陋的。 有更好的解决方案可以跨浏览器工作吗

我得到了错误的结果,因为日期被视为UTC:

Wed Mar 15 2017 20:26:00 GMT+0800 (AWST)
这实际上是ES5规范中的一个错误(该规范说,并没有时区指示器意味着UTC,这和它意味着UTC的子集不一致)。ES2015纠正了这一说法,即没有时区指示器意味着本地时间(符合ISO-8601),但如果在仅日期字符串上使用,则会导致与现有代码的兼容性问题(如
“2018-01-17”
)。因此,ES2016必须再次更新,并且自那时以来一直保持稳定。如果没有时区指示器,则:

  • 仅日期字符串(如
    “2019-05-20”
    )以UTC格式解析
  • 日期/时间字符串(如
    “2019-05-20T10:00”
    )以本地时间进行解析
由于规范混乱,有一段时间我们混合使用了使用旧ES5行为、ES2015行为或ES2016行为的JavaScript引擎。还有一个重要的平台仍然存在不正确的行为:iOS

截至2019年5月20日更新的答复:

  • 桌面版Chrome、Firefox、Edge甚至IE11版本都正确实施了ES2016+规范
  • Safari(桌面或iOS)错误地解析日期/时间字符串,而UTC中没有时区指示器
  • 所有当前的iOS浏览器(当然是Safari,还有Chrome、Firefox、Brave、Dolphin…)也错误地解析日期/时间字符串,而UTC中没有时区指示器。这是因为iOS JavaScript引擎JavaScriptCore(JSC)实现不正确,非苹果iOS应用程序无法分配可执行内存,因此浏览器无法使用他们通常使用的引擎(Chrome的V8、Firefox的SpiderMonkey等),因为这些引擎优化了需要在运行时创建可执行代码的引擎。所以他们用JSC代替。(Chrome的V8最近添加了一个“无JIT”的纯解释器版本,因此Chrome可能会也可能不会开始使用它而不是JSC。)
您可以在此处检查当前浏览器:

var may20=新日期(“2019-05-20”);
//如果解析为UTC,则UTC小时数应为0
log(可能20.getUTCHours()==0?“确定:”:“错误:”,可能20.toLocaleString());
var may20At10=新日期(“2019-05-20T10:00”);
//如果在本地时间解析,则本地小时数应为10
log(may20At10.getHours()==10?“确定:”:“错误:”,may20At10.tolocalString())
我得到了错误的结果,因为日期被视为UTC:

Wed Mar 15 2017 20:26:00 GMT+0800 (AWST)
这实际上是ES5规范中的一个错误(该规范说,并没有时区指示器意味着UTC,这和它意味着UTC的子集不一致)。ES2015纠正了这一说法,即没有时区指示器意味着本地时间(符合ISO-8601),但如果在仅日期字符串上使用,则会导致与现有代码的兼容性问题(如
“2018-01-17”
)。因此,ES2016必须再次更新,并且自那时以来一直保持稳定。如果没有时区指示器,则:

  • 仅日期字符串(如
    “2019-05-20”
    )以UTC格式解析
  • 日期/时间字符串(如
    “2019-05-20T10:00”
    )以本地时间进行解析
由于规范混乱,有一段时间我们混合使用了使用旧ES5行为、ES2015行为或ES2016行为的JavaScript引擎。还有一个重要的平台仍然存在不正确的行为:iOS

截至2019年5月20日更新的答复:

  • 桌面版Chrome、Firefox、Edge甚至IE11版本都正确实施了ES2016+规范
  • Safari(桌面或iOS)错误地解析日期/时间字符串,而UTC中没有时区指示器
  • 所有当前的iOS浏览器(当然是Safari,还有Chrome、Firefox、Brave、Dolphin…)也错误地解析日期/时间字符串,而UTC中没有时区指示器。这是因为iOS JavaScript引擎JavaScriptCore(JSC)实现不正确,非苹果iOS应用程序无法分配可执行内存,因此浏览器无法使用他们通常使用的引擎(Chrome的V8、Firefox的SpiderMonkey等),因为这些引擎优化了需要在运行时创建可执行代码的引擎。所以他们用JSC代替。(Chrome的V8最近添加了一个“无JIT”的纯解释器版本,因此Chrome可能会也可能不会开始使用它而不是JSC。)
您可以在此处检查当前浏览器:

var may20=新日期(“2019-05-20”);
//如果解析为UTC,则UTC小时数应为0
log(可能20.getUTCHours()==0?“确定:”:“错误:”,可能20.toLocaleString());
var may20At10=新日期(“2019-05-20T10:00”);
//如果在本地时间解析,则本地小时数应为10
log(may20At10.getHours()==10?“确定:”:“错误:”,may20At10.tolocalString())
我得到了错误的结果,因为日期被视为UTC:

Wed Mar 15 2017 20:26:00 GMT+0800 (AWST)
鉴于:

new Date('2017-03-15T12:26')
IE版本8之前的版本将其视为无效字符串,IE 9+将其视为UTC。Firefox38将其视为本地的

如果我使用空格…结果是正确的

直到您尝试Safari并获得无效日期

但是,这在Safari上不起作用(没有T)。Safari实际上会抛出一个错误(!)

是的,两个结果都是a