str*_*str 13 javascript string time datetime date
使用new Date
或Date.parse
在JavaScript中,我不能只传递任意日期格式.根据格式,我得到的日期与我想要的不同,甚至Invalid Date
不是日期对象.某些日期格式在一个浏览器中工作,但在其他浏 那么我应该使用哪种日期时间格式?
其他问题:
所有浏览器都支持相同的格式吗?Mozilla Firefox,Google Chrome,Microsoft Internet Explorer,Microsoft Edge和Apple Safari如何处理日期时间字符串?那么Node.js呢?
是否需要考虑本地日期格式?例如,如果我住在瑞士并且日期格式是30.07.2018,我可以使用new Date('30.07.2018')
吗?
是否需要考虑当地时区?
如何从日期对象中获取日期时间字符串?
如何检测无效的日期时间字符串?
Moment.js等日期库如何处理日期字符串?
如果您没有注意到,我回答了我自己的问题(为什么?).
str*_*str 27
JavaScript正式支持简化 ISO 8601扩展格式.格式如下:YYYY-MM-DDTHH:mm:ss.sssZ
.该字母T
是日期/时间分隔符,Z
是指定为Z
(对于UTC)或时间表达式之一+
或-
之后的时区偏移量HH:mm
.可以省略该格式的某些部分(例如时间).
请注意,年份必须至少有四位数,月/日/小时/分钟/秒必须正好有两位数,而毫秒必须正好有三位数.例如,99-1-1
不是有效的日期字符串.
以下是有效日期(时间)字符串的一些示例:
2018-12-30
2018-12-30T20:59
2018-12-30T20:59:00
2018-12-30T20:59:00.000Z
2018-12-30T20:59:00.000+01:00
2018-12-30T20:59:00.000-01:00
省略时区偏移时,日期时间将被解释为用户本地时间.当您完全省略时间时,日期将被解释为UTC.
重要提示:所有现代且相当旧的浏览器和实现都支持根据规范的全长日期时间格式.
但是,在没有时区的日期(时间)字符串处理方面存在差异(有关详细信息,请参阅下面的"缺少时区偏移").你应该不是没有时区(状态2018)使用日期时间字符串.而是以毫秒为单位传递unix时间戳,或者将日期的不同部分的参数分隔给Date
构造函数.
大多数浏览器也支持其他一些格式,但它们没有指定,因此不能以相同的方式在所有浏览器中工作.如果有的话,您应该只使用上面解释的日期时间字符串格式.在其他浏览器中甚至在同一浏览器的其他版本中,其他所有格式都可能会中断.
如果您遇到Invalid Date
而不是日期对象,则很可能使用的是无效的日期时间字符串.
现在有更多细节.
ECMAScript(JavaScript语言实现的规范)从一开始就支持new Date
(规范)和Date.parse
(规范)中的日期字符串.但是,第一个版本实际上并未指定日期时间格式.这在2009年改变了,当时ES5引入了日期时间格式的规范.
ECMAScript中指定的日期时间字符串格式为简化了的ISO 8601扩展格式.格式如下:YYYY-MM-DDTHH:mm:ss.sssZ
.
YYYY
是公历格里高利历中0000年至9999年的小数位数.-
(连字符)在字符串中字面上出现两次.MM
是从01(1月)到12(12月)的一年中的一个月.DD
是从01到31的月中的某一天.T
字面上出现在字符串中,表示时间元素的开头.HH
是自午夜以来经过的完整小时数,为00到24之间的两位小数.:
(冒号)在字符串中出现两次.mm
是自小时开始以来的完整分钟数,为00到59之间的两位小数.ss
是自分钟开始以来的完整秒数,为00到59之间的两位小数..
(点)字面上出现在字符串中.sss
是自第二个开始以来的完整毫秒数,为三位十进制数.Z
是指定为"Z"(对于UTC)或"+"或" - "后跟时间表达式的时区偏移量HH:mm
尚未指定其他日期时间格式.ECMAScript不会考虑任何用户本地日期时间格式,这意味着您不能使用国家或地区特定的日期时间格式.
该规范还提到,如果"字符串不符合[指定的]格式,则该函数可能会回退到任何特定于实现的启发式或特定于实现的日期格式",这可能导致不同浏览器中的不同日期.
该规范还包括如下更短的格式.
此格式包括仅限日期的表单:
YYYY
YYYY-MM
YYYY-MM-DD
它还包括"日期时间"表单,其中包含上述仅限日期的表单之一,紧接着是以下时间表格之一,并附加了可选的时区偏移量:
THH:mm
THH:mm:ss
THH:mm:ss.sss
[...] If the
MM
orDD
fields are absent"01"
is used as the value. If theHH
,mm
, orss
fields are absent"00"
is used as the value and the value of an absentsss
field is"000"
. When the time zone offset is absent, date-only forms are interpreted as a UTC time and date-time forms are interpreted as a local time.
See "Missing Time Zone Offset" below for more information on the lacking browser support.
Illegal values (out-of-bounds as well as syntax errors) in a format string means that the format string is not a valid instance of this format.
For example, new Date('2018-01-32')
and new Date('2018-02-29')
will result in a Invalid Date
.
The date time format of ECMAScript also specifies extended years which are six digit year values.
An example of such an extended year string format looks like +287396-10-12T08:59:00.992Z
which denotes a date in the year 287396 A.D.
Extended years can either be positive or negative.
ECMAScript specifies a wide range of date object properties.
Given a valid date object, you can use Date.prototype.toISOString()
to get a valid date time string.
Note that the time zone is always UTC.
new Date().toISOString() // "2018-08-05T20:19:50.905Z"
Run Code Online (Sandbox Code Playgroud)
It is also possible to detect whether a date object valid or an Invalid Date
using the following function.
function isValidDate(d) {
return d instanceof Date && !isNaN(d);
}
Run Code Online (Sandbox Code Playgroud)
Source and more information can be found in Detecting an "invalid date" Date instance in JavaScript.
The following date time formats are all valid according to the specification and should work in every browser, Node.js or other implementation that supports ES2016 or higher.
2018
2018-01
2018-01-01
2018-01-01T00:00
2018-01-01T00:00:00
2018-01-01T00:00:00.000
2018-01-01T00:00:00.000Z
2018-01-01T00:00:00.000+01:00
2018-01-01T00:00:00.000-01:00
+002018-01-01T00:00:00.000+01:00
Run Code Online (Sandbox Code Playgroud)
Note that the following examples are invalid as per the specification. However, that does not mean that no browser or other implementation interprets them to a date. Please do not use any of the date time formats below as they are non-standard and might fail in some browsers or browser versions.
2018-1-1 // month and date must be two digits
2018-01-01T0:0:0.0 // hour/minute/second must be two digits, millisecond must be three digits
2018-01-01 00:00 // whitespace must be "T" instead
2018-01-01T00 // shortest time part must have format HH:mm
2018-01-01T00:00:00.000+01 // time zone must have format HH:mm
Run Code Online (Sandbox Code Playgroud)
Today, every modern and reasonably old browser supports the date time format that was introduced with the ES5 specification in 2009.
However, even today (Status 2018) there are different implementations for date time strings without a time zone (see "Missing Time Zone Offset" below).
If you need to support older browsers or use strings without a time zone, you should not use date time strings.
Instead, pass a number of milliseconds since January 1, 1970, 00:00:00 UTC
or two or more arguments representing the different date parts to the Date
constructor.
ES5.1 incorrectly states that the value of an absent time zone offset is “Z”
which contradicts with ISO 8601.
This mistake was fixed in ES6 (ES2015) and extended on in ES2016 (see "Changes to the ECMAScript Specifications" below).
As of ES2016, date time strings without a time zone are parsed as local time while date only strings are parsed as UTC.
According to this answer, some implementations never implemented the behaviour specified in ES5.1.
One of them seems to be Mozilla Firefox.
Other browsers that seem to be compliant with the specification of ES2016 (and higher) are Google Chrome 65+, Microsoft Internet Explorer 11, and Microsoft Edge.
The current version of Apple Safari (11.1.2) is not compliant as it erroneously parses date time strings without a time zone (e.g. 2018-01-01T00:00
) as UTC instead of local time.
ES5 introduced a specification for date time strings in 2009. Before that, there were no specified formats that were supported by all browsers. As a result, each browser vendor added support for different formats which often did not work accross different browsers (and versions). For a small example of ancient history, see date-formats.
Most browsers still support those legacy formats in order to not break the backward compatibility of older websites. But it is not safe to rely on those non-standard formats as they might be inconsistent or get removed at any time.
Date.prototype.toString()
and Date.prototype.toUTCString()
ES2018 for the first time specified the date format that is returned by Date.prototype.toString()
and Date.prototype.toUTCString()
.
Already before that, the ECMA Specification required the Date
constructor and Date.parse
to correctly parse the formats returned by those methods (even though it did not specify a format before 2018).
An example return value of Date.prototype.toString()
may look like this:
Sun Feb 03 2019 14:27:49 GMT+0100 (Central European Standard Time)
Run Code Online (Sandbox Code Playgroud)
Note that the timezone name within brackets is optional and the exact name is "implementation-dependent".
Date.prototype.toUTCString()
returns a date in a similar format as Date.prototype.toString()
but with a zero timezone offset. An example format may look like this:
Sun, 03 Feb 2019 13:27:49 GMT
Run Code Online (Sandbox Code Playgroud)
Note that there is a comma ,
after the weekday and day month are reversed compared to Date.prototype.toUTCString()
.
As those formats have only been specified in 2018, you should not rely on them working equally in different implementations (especially older browsers).
Node.js is running on the V8 JavaScript engine which is also used in Google Chrome. So the same specification regarding the date time string format applies. As the code runs in the backend though, the user local time does not influence the time zones but only the settings on the server do. Most platform as a service (PaaS) provider that host Node.js applications use UTC as their default time zone.
Moment.js is a very popular library to help with the handling of dates in JavaScript and it also supports more formats than ECMAScript specifies. In addition, Moment.js also supports creating date objects based on a string and a arbitrary format.
Luxon supports parsing of ISO 8601, HTTP, RFC2822, SQL, and arbitrary formats. But only using different functions for different date time formats.
A list of notable changes in the ECMAScript specifications regarding date time string formats.
Changes in ES2018
Introduces a specification for the date formats returned by Date.prototype.toString()
and Date.prototype.toUTCString()
.
Changes in ES2017
No notable changes.
Changes in ES2016
If the time zone offset is absent, the date-time is interpreted as a local time.When the time zone offset is absent, date-only forms are interpreted as a UTC time and date-time forms are interpreted as a local time.
Changes in ES6 (ES2015)
The value of an absent time zone offset is“Z”
.If the time zone offset is absent, the date-time is interpreted as a local time.
From Corrections and Clarifications in ECMAScript 2015 with Possible Compatibility Impact:
If a time zone offset is not present, the local time zone is used. Edition 5.1 incorrectly stated that a missing time zone should be interpreted as
"z"
.
See Date Time String Format: default time zone difference from ES5 not web-compatible for more details on that change.
Changes in ES5.1
If the
MM
orDD
fields are absent“01”
is used as the value. If theHH
,mm
, orss
fields are absent“00”
is used as the value and the value of an absentsss
field is“000”
. The value of an absent time zone offset is“Z”
.
Changes in ES5
First introduction of a date time string format to the ECMAScript specification.
ECMAScript defines a string interchange format for date-times based upon a simplification of the ISO 8601 Extended Format. The format is as follows:
YYYY-MM-DDTHH:mm:ss.sssZ
Also introduces Date.prototype.toISOString()
which returns a date time string in that specified format.
Changes in ES3
Deprecates Date.prototype.toGMTString()
and replaces it with Date.parse(x.toUTCString())
in the section mentioning that the format returned by these methods must be correctly parseable by implmentations of Date.parse
. Note that the format returned by Date.parse(x.toUTCString())
is "implementation-dependent".
Changes in ES2
No notable changes.
Initial Specification: ES1
ES1 introduced date time strings to be used in new Date(value)
and Date.parse(value)
.
However, it did not specify an actual date (time) format, it even states that
[...] the value produced by
Date.parse
is implementation dependent [...]
The specification also mentions that
If
x
is any Date object [...], then all of the following expressions should produce the same numeric value in that implementation [...]:
- [...]
Date.parse(x.toString())
Date.parse(x.toGMTString())
However, the returned value of both Date.prototype.toString()
and Date.prototype.toGMTString()
were specified as "implementation dependent".
归档时间: |
|
查看次数: |
7582 次 |
最近记录: |