Date.parse() not working properly in Mozilla Firefox JavaScript - javascript

I have the string dateTime value "01-01-2013 12:00:00 AM" and parsed to DateTime using Date.parse("01-01-2013 12:00:00 AM"). This is working fine in Google Chrome and IE browser. But not working in Firefox. Anyone help how to parse this specific string to dateTime value in Mozilla Firefox.
Thanks,
Bharathi.

TL;DR You're using an invalid date format for this context, which Chrome and IE just happen to handle.
Full answer:
The specification only requires a JavaScript implementation to recognize certain formats in Date.parse. Specifically,
It accepts the RFC2822 / IETF date syntax (RFC2822 Section 3.3), e.g.
"Mon, 25 Dec 1995 13:30:00 GMT". It understands the continental US
time zone abbreviations, but for general use, use a time zone offset,
for example, "Mon, 25 Dec 1995 13:30:00 +0430" (4 hours, 30 minutes
east of the Greenwich meridian). If a time zone is not specified and
the string is in an ISO format recognized by ES5, UTC is assumed. GMT
and UTC are considered equivalent. The local time zone is used to
interpret arguments in RFC2822 Section 3.3 format (or any format not
recognized as ISO 8601 in ES5) that do not contain time zone
information.
ECMAScript 5 ISO-8601 format support
The date time string may be in ISO 8601 format. For example,
"2011-10-10" (just date) or "2011-10-10T14:48:00" (date and time) can
be passed and parsed.
Your example, 01-01-2013 12:00:00 AM, is not one of those formats. Some browsers may parse it anyway, depending on the JavaScript engine they are using, but it's non-standard. Chrome and IE happen to recognize it, but Firefox returns NaN, which is compliant with the spec:
The ECMAScript specification states: If the String does not conform to
the standard format the function may fall back to any
implementation–specific heuristics or implementation–specific parsing
algorithm. Unrecognizable strings or dates containing illegal element
values in ISO formatted strings shall cause Date.parse() to return
NaN.
See this documentation for more details.

Related

how to convert datetime to number in javascript [duplicate]

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?).
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.
Legacy Date Time Formats
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)
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
Note that there is a comma , after the weekday and day month are reversed compared to Date.prototype.toString().
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
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.
Date Time Libraries
Moment.js
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
Luxon supports parsing of ISO 8601, HTTP, RFC2822, SQL, and arbitrary formats. But only using different functions for different date time formats.
Changes to the ECMAScript Specifications
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 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”. 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".
So which date time formats should I use?
The general recommendation is to not use the built-in parser at all as it's unreliable, so the answer to "should" is "none". See Why does Date.parse give incorrect results?
However, as str says, you can likely use the format specified in ECMA-262 with a timezone: YYYY-MM-DDTHH:mm:ss.sssZ or YYYY-MM-DDTHH:mm:ss.sss±HH:mm, don't trust any other format.
Do all browser support the same formats?
No.
How do Mozilla Firefox, Google Chrome, Microsoft Internet Explorer, Microsoft Edge, and Apple Safari handle date time strings?
Differently. Anything other than the format in ECMA-262 is implementation dependent, and there are bugs in parsing the the ECMA-262 format.
What about Node.js?
Likely different again, see above.
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')?
Maybe. Since it's not the standard format, parsing is implementation dependent, so maybe, maybe not.
Does it take the local time zone into consideration?
It uses the host timezone offset where the string is parsed as local and to generate the string displayed using local times. Otherwise it uses UTC (and the internal time value is UTC).
How can I get a date time string from a date object?
Date.parse.toString, or see Where can I find documentation on formatting a date in JavaScript?
How can I detect invalid date time strings?
One of the first 3 answers here should answer that.
How do date libraries like Moment.js handle date strings?
They parse them based on either a default or provided format. Read the source (e.g. fecha.js is a simple parser and formatter with well written, easy to follow code).
A parser isn't hard to write, but trying to guess the input format (as built-in parsers tend to do) is fraught, unreliable and inconsistent across implementations. So the parser should require the format to be provided unless the input string is in the parser's default format.
PS
There are changes to the formats of strings that implementations must support for parsing and formatting in ECMAScript 2019 (currently in draft), but I think the general advice to avoid the built–in parser will stand for some time yet.

Date Object not working with specific timezone [duplicate]

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?).
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.
Legacy Date Time Formats
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)
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
Note that there is a comma , after the weekday and day month are reversed compared to Date.prototype.toString().
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
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.
Date Time Libraries
Moment.js
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
Luxon supports parsing of ISO 8601, HTTP, RFC2822, SQL, and arbitrary formats. But only using different functions for different date time formats.
Changes to the ECMAScript Specifications
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 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”. 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".
So which date time formats should I use?
The general recommendation is to not use the built-in parser at all as it's unreliable, so the answer to "should" is "none". See Why does Date.parse give incorrect results?
However, as str says, you can likely use the format specified in ECMA-262 with a timezone: YYYY-MM-DDTHH:mm:ss.sssZ or YYYY-MM-DDTHH:mm:ss.sss±HH:mm, don't trust any other format.
Do all browser support the same formats?
No.
How do Mozilla Firefox, Google Chrome, Microsoft Internet Explorer, Microsoft Edge, and Apple Safari handle date time strings?
Differently. Anything other than the format in ECMA-262 is implementation dependent, and there are bugs in parsing the the ECMA-262 format.
What about Node.js?
Likely different again, see above.
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')?
Maybe. Since it's not the standard format, parsing is implementation dependent, so maybe, maybe not.
Does it take the local time zone into consideration?
It uses the host timezone offset where the string is parsed as local and to generate the string displayed using local times. Otherwise it uses UTC (and the internal time value is UTC).
How can I get a date time string from a date object?
Date.parse.toString, or see Where can I find documentation on formatting a date in JavaScript?
How can I detect invalid date time strings?
One of the first 3 answers here should answer that.
How do date libraries like Moment.js handle date strings?
They parse them based on either a default or provided format. Read the source (e.g. fecha.js is a simple parser and formatter with well written, easy to follow code).
A parser isn't hard to write, but trying to guess the input format (as built-in parsers tend to do) is fraught, unreliable and inconsistent across implementations. So the parser should require the format to be provided unless the input string is in the parser's default format.
PS
There are changes to the formats of strings that implementations must support for parsing and formatting in ECMAScript 2019 (currently in draft), but I think the general advice to avoid the built–in parser will stand for some time yet.

Safari and Chrome showing different results of new Date() [duplicate]

I want to convert date string to Date by javascript, use this code:
var date = new Date('2013-02-27T17:00:00');
alert(date);
'2013-02-27T17:00:00' is UTC time in JSON object from server.
But the result of above code is different between Firefox and Chrome:
Firefox returns:
Wed Feb 27 2013 17:00:00 GMT+0700 (SE Asia Standard Time)
Chrome returns:
Thu Feb 28 2013 00:00:00 GMT+0700 (SE Asia Standard Time)
It's different 1 day, the correct result I would expect is the result from Chrome.
Demo code: http://jsfiddle.net/xHtqa/2/
How can I fix this problem to get the same result from both?
The correct format for UTC would be 2013-02-27T17:00:00Z (Z is for Zulu Time). Append Z if not present to get correct UTC datetime string.
Yeah, unfortunately the date-parsing algorithms are implementation-dependent. From the specification of Date.parse (which is used by new Date):
The String may be interpreted as a local time, a UTC time, or a time in some other time zone, depending on the contents of the String. The function first attempts to parse the format of the String according to the rules called out in Date Time String Format (15.9.1.15). If the String does not conform to that format the function may fall back to any implementation-specific heuristics or implementation-specific date formats.
To make the Date constructor not (maybe) use the local timezone, use a datetime string with timezone information, e.g. "2013-02-27T17:00:00Z". However, it is hard to find a format that is reliable parsed by every browser - the ISO format is not recognised by IE<8 (see JavaScript: Which browsers support parsing of ISO-8601 Date String with Date.parse). Better, use a unix timestamp, i.e. milliseconds since unix epoch, or use a regular expression to break the string down in its parts and then feed those into Date.UTC.
I found one thing here. It seems the native Firefox Inspector Console might have a bug:
If I run "new Date()" in the native Inspector, it shows a date with wrong timezone, GMT locale, but running the same command in the Firebug Extension Console, the date shown uses my correct timezone (GMT-3:00).
Noticed that FireFox wasn't returning the same result as Chrome. Looks like the format you use in kendo.toString for date makes a difference.
The last console result is what I needed:
Try using moment.js. It goes very well and in similar fashion with all the browsers. comes with many formatting options. use moment('date').format("") instead of New Date('date')

what is wrong with this date format

This works in Chrome but not in Firefox.
new Date("2013-06-03 17:09:06-0400")
Works fine in Chrome
Gives 'NaN' in Firefox.
I would appreciate any help.
Take a look at Mozilla Developer Network's Date and Date.parse documentation.
Specifically, it states:
Alternatively, the date/time string may be in ISO 8601 format. Starting with JavaScript 1.8.5 (Firefox 4), a subset of ISO 8601 is supported. For example, "2011-10-10" (just date) or "2011-10-10T14:48:00" (date and time) can be passed and parsed.
If you throw a 'T' in between the date and the time you get:
new Date("2013-06-03T17:09:06-0400")
=> Mon Jun 03 2013 14:09:06 GMT-0700 (PDT)
In both Chrome and Mozilla, although you have to account for the the current timezone (thus PDT) of the user's system.
In my experience, the only reliable way to construct a date object from a string in JavaScript is to parse the string yourself, and then use the version of the constructor that takes a separate numeric parameter for each field.
The string-based constructor is far too prone to issues with locale-related parsing errors.

Javascript new Date(str) - different parsing rules

I tried this in the Chrome JS console, with my locale time zone set as PST:
(new Date("07-15-2005"))
=> Fri Jul 15 2005 00:00:00 GMT-0700 (PDT)
(new Date("07-15-2005")).getTime();
=> 1121410800000
but....
(new Date("2005-07-15"))
=> Thu Jul 14 2005 17:00:00 GMT-0700 (PDT)
(new Date("2005-07-15")).getTime();
=> 1121385600000
I was expecting string parsing to occur in both. But I can't make out why when format YYYY-MM-DD is used, it assumes a timezone offset. It's as if I'm expressing "2005-07-15" in my local TZ, but "07-15-2005" is expressed in UTC.
Is the correct explanation?
The implementation seems to be vendor specific, however looking at the documentation of date parse we see that as of 1.8.5 javascript supports both RFC2822 dates and ISO 8601 dates.
As per the Date.UTC documentation ISO 8601 dates are assumed to be in UTC time if not otherwise specified and thus the timezone difference is automatically added.
RFC2822 dates seem to be assumed as local times and as such are not modified.
I cannot seem to replicate your results, but the results seem to differ from browser to browser.
See: http://jsfiddle.net/f7DMV/
In Firefox and Opera, I get only the middle line parsing correctly, the others are Invalid Dates.
In Chrome, both the first and the second line parse correctly (and don't differ), but the last one is still Invalid.
It will vary from browser to browser. The ECMA262 spec says any string which is not in YYYY-MM-DD format and is passed to the Date function, it may fall back to implementation-specific heuristics or implementation-specific date formats.

Categories

Resources