从字符串创建日期 [英] Create date from string

查看:87
本文介绍了从字符串创建日期的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a two strings 2017-03-15 (date) and 12:26 (time). I want to create a localised date object from it, without using a library.

现在记住,这里是: Tue Mar 14 2017 12: 26:33 GMT + 0800(AWST),如果我这样做:

Remembering that here right now is: Tue Mar 14 2017 12:26:33 GMT+0800 (AWST), if I do:

new Date( date + 'T' + time )

由于日期被认为是UTC,我得到了错误的结果:

I get the wrong result as the date is considered 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实际上会抛出错误(!)。

However, this will NOT work on Safari (not without the T). Safari will actually throw an error (!).

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

I realise that parsing strings as date depends on the implementation. So, the only way to do it "right" would be:

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

new Date( dateSplit[0], dateSplit[1] - 1, dateSplit[2], timeSplit[ 0 ], timeSplit[ 1 ] )

但这只是。所以。丑陋。
是否有更好的解决方案可以跨浏览器使用?

But it's just. So. Ugly. Is there a better solution that will work across browsers?

推荐答案


错误的结果,因为日期被认为是UTC:

I get the wrong result as the date is considered UTC:

这实际上是ES5规范中的错误(表示没有时区指示符表示UTC ,它与 ISO-8601标准不一致。 。 ES2015更正为说没有时区指示符表示本地时间(与ISO-8601保持一致),但是当在仅日期的字符串上使用时,这会导致与现有代码的兼容性问题(例如 2018-01 -17 )。因此ES2016必须再次对其进行更新,此后一直保持稳定。如果没有时区指示符,则:

That was actually an error in the ES5 specification (which said that no timezone indicator meant UTC, which is at odds with the ISO-8601 standard it was meant to be a subset of). ES2015 corrected it to say that no timezone indicator meant local time (in keeping with ISO-8601), but that would have caused compatibility problems with existing code when used on date-only strings (like "2018-01-17"). So ES2016 had to update it again, and it's been stable since. If there's no timezone indicator, then:


  • 一个仅日期字符串(例如 2019-05-20 )以UTC进行解析

  • 日期/时间字符串(例如 2019-05-20T10:00 )在本地时间被解析

  • A date-only string (such as "2019-05-20") is parsed in UTC
  • A date/time string (such as "2019-05-20T10:00") is parsed in local time

出于规范混乱的原因,有一段时间,我们混合使用了旧的ES5行为,ES2015行为或ES2016行为的JavaScript引擎。并且一个重要的平台仍然具有错误的行为:iOS。

As a result of this spec confusion, for a while we had a mix of JavaScript engines that used the old ES5 behavior, the ES2015 behavior, or the ES2016 behavior. And one significant platform still has incorrect behavior: iOS.

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

As of this updated answer on May 20th, 2019:


  • 台式机版本的Chrome,Firefox,Edge甚至IE11都正确实现了ES2016 +规范。

  • Safari(台式机或iOS)在UTC中错误地解析了没有时区指示符的日期/时间字符串。

  • 所有当前的 iOS 浏览器(当然还有Safari浏览器,还有Chrome,Firefox,Brave,Dolphin ...)还错误地解析了没有UTC中时区指示符的日期/时间字符串。这是因为iOS JavaScript引擎JavaScriptCore(JSC)错误地实现了此功能,并且非Apple iOS应用程序无法分配可执行内存,因此浏览器无法使用它们通常使用的引擎(Chrome的V8,Firefox的SpiderMonkey等)。 ),因为它们是优化引擎,需要在运行时创建可执行代码。因此,他们改用JSC。 (Chrome的V8最近添加了无需JIT的纯解释程序版本,因此Chrome可能会或可能不会开始使用该版本而不是JSC。)

  • Desktop versions of Chrome, Firefox, Edge, and even IE11 all correctly implement the ES2016+ specification.
  • Safari (desktop or iOS) incorrectly parses date/time strings without timezone indicators in UTC.
  • All current iOS browsers (Safari of course, but also Chrome, Firefox, Brave, Dolphin...) also incorrectly parse date/time strings without timezone indicators in UTC. This is because the iOS JavaScript engine, JavaScriptCore (JSC), implements this incorrectly, and non-Apple iOS applications can't allocate executable memory, so browsers can't use the engines they normally use (Chrome's V8, Firefox's SpiderMonkey, etc.) because those are optimizing engines that need to create executable code at runtime. So they use JSC instead. (Chrome's V8 has recently added a "JIT-less" pure interpreter version, so Chrome may or may not start using that rather than JSC.)

您可以在此处检查当前的浏览器:

You can check your current browser here:

var may20 = new Date("2019-05-20");
// UTC hours should be 0 if that was parsed as UTC
console.log(may20.getUTCHours() === 0 ? "OK:" : "Error:", may20.toLocaleString());

var may20At10 = new Date("2019-05-20T10:00");
// Local hours should be 10 if that was parsed in local time
console.log(may20At10.getHours() === 10 ? "OK:" : "Error:", may20At10.toLocaleString());

(除非您处于全年使用GMT的几个西非国家之一,否则该支票才有效。它依赖于UTC和当地时间在2019年5月20日彼此不同。因此在英国工作的原因是,尽管英国一年中大部分时间使用格林尼治标准时间,但支票使用的日期是英国夏令时[GMT + 0100];它之所以在纽约有效,是因为纽约从未参加过格林尼治标准时间;但这在廷巴克图不起作用,因为廷巴克图全年使用GMT 。)

(That check works unless you're in one of the several west African countries that use GMT year-round. It relies on UTC and local time being different from one another on May 20th, 2019. So it works in the UK because although the UK uses GMT much of the year, it's on British Summer Time [GMT+0100] for the date the check uses; and it works in New York because New York is never on GMT; but it doesn't work in Timbuktu because Timbuktu uses GMT year-round.)


但是,这将无法在Safari上运行(并非没有T)。

However, this will NOT work on Safari (not without the T).

对。 JavaScript引擎需要支持的日期/时间格式是ISO-8601子集在此处定义(以及从 toString 返回的任何值,但规格中未定义;它必须是双向的)。并且如上所述,至少在2019年5月20日撰写本文时,Safari没有正确实现该规范。

Right. The only date/time format that a JavaScript engine is required to support is the ISO-8601 subset defined here (and also whatever it returns from toString, but that isn't defined in the spec; it just has to be two-way). And as noted above, at least as of this writing on May 20th, 2019, Safari doesn't implement the specification correctly.


只是。所以。丑陋。是否有更好的解决方案可在所有浏览器上使用?

But it's just. So. Ugly. Is there a better solution that will work across browsers?

这一点都不难看。毕竟,这就是 Date 构造函数必须执行的操作。将其放入您的标准库中,您就可以使用了。

It's not ugly at all. That is, after all, what the Date constructor has to do to figure it out. Put it in your standard library and you're good to go.

这篇关于从字符串创建日期的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆