Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
94 views
in Technique[技术] by (71.8m points)

What are valid Date Time Strings in JavaScript?

When using new Date or Date.parse in JavaScript, I cannot just pass arbitrary date formats. Depending on the format, I get a different date than I wanted to or even Invalid Date instead of a date object. Some date formats work in one browser but not in others. So which date time formats should I use?

Additional questions:

  • Do all browsers support the same formats? How do Mozilla Firefox, Google Chrome, Microsoft Internet Explorer, Microsoft Edge, and Apple Safari handle date time strings? What about Node.js?

  • Does it take the local date format into consideration? E.g. if I live in Switzerland and the date format is 30.07.2018, can I use new Date('30.07.2018')?

  • Does it take the local time zone into consideration?

  • How can I get a date time string from a date object?

  • How can I detect invalid date time strings?

  • How do date libraries like Moment.js handle date strings?

In case you did not notice, I answered my own question (why?).

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The Essentials

JavaScript officially supports a simplification of the ISO 8601 Extended Format. The format is as follows: YYYY-MM-DDTHH:mm:ss.sssZ. The letter T is the date/time separator and Z is the time zone offset specified as Z (for UTC) or either + or - followed by a time expression HH:mm. Some parts (e.g. the time) of that format can be omitted.

Note that years must have at least four digits, month/day/hours/minutes/seconds must have exactly two digits, and milliseconds must have exactly three digits. For example, 99-1-1 is not a valid date string.

These are some examples of valid date (time) strings:

  • 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

When you omit the time zone offset, date-times are interpreted as user local time. When you omit the time altogether, dates are interpreted as UTC.

Important: All modern and reasonably old browsers and implementations support the full-length date time format according to the specification. However, there are differences in the handling of date (time) strings without a time zone (see "Missing Time Zone Offset" below for details). You should not use date time strings without a time zone (Status 2018). Instead pass a unix timestamp in milliseconds or separate arguments for different parts of the date to the Date constructor.

Most browser also support some other formats but they are not specified and thus don't work in all browsers the same way. If at all, you should only use the date time string formats explained above. Every other format might break in other browsers or even in other versions of the same browser.

If you run into Invalid Date instead of a date object, you most probably are using an invalid date time string.


And now with a little more detail.

Date Time String Format

ECMAScript (the specification that the JavaScript language implements) has been supporting date strings in new Date (specification) and Date.parse (specification) since its inception. However, the first versions did not actually specify a date time format. This changed in 2009 when ES5 was introduced with a specification of a date time format.

The Basics

ECMAScript specifies the Date Time String Format as a simplification of the ISO 8601 Extended Format. The format is as follows: YYYY-MM-DDTHH:mm:ss.sssZ.

  • YYYY is the decimal digits of the year 0000 to 9999 in the proleptic Gregorian calendar.
  • - (hyphen) appears literally twice in the string.
  • MM is the month of the year from 01 (January) to 12 (December).
  • DD is the day of the month from 01 to 31.
  • T appears literally in the string, to indicate the beginning of the time element.
  • HH is the number of complete hours that have passed since midnight as two decimal digits from 00 to 24.
  • : (colon) appears literally twice in the string.
  • mm is the number of complete minutes since the start of the hour as two decimal digits from 00 to 59.
  • ss is the number of complete seconds since the start of the minute as two decimal digits from 00 to 59.
  • . (dot) appears literally in the string.
  • sss is the number of complete milliseconds since the start of the second as three decimal digits.
  • Z is the time zone offset specified as "Z" (for UTC) or either "+" or "-" followed by a time expression HH:mm

The specification also mentions that if "the String does not conform to [the specified] format the function may fall back to any implementation-specific heuristics or implementation-specific date formats" which might result in different dates in different browsers.

ECMAScript does not take any user local date time formats into account which means that you can not use country or region-specific date time formats.

Short Date (and Time) Forms

The specification also includes shorter formats as follows.

This format includes date-only forms:

  • YYYY
  • YYYY-MM
  • YYYY-MM-DD

It also includes “date-time” forms that consist of one of the above date-only forms immediately followed by one of the following time forms with an optional time zone offset appended:

  • THH:mm
  • THH:mm:ss
  • THH:mm:ss.sss

Fallback Values

[...] If the MM or DD fields are absent "01" is used as the value. If the HH, mm, or ss fields are absent "00" is used as the value and the value of an absent sss 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.

Out of Bound Values

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.

Extended Years

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.

Date API

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"

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);
}

Source and more information can be found in Detecting an “invalid date” Date instance in JavaScript.

Examples

Valid Date Time Formats

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

Invalid Date Time Formats

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

Browser Support

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.

Missing Time Zone Offset

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.

Leg


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...