Javascript: Which Browsers Support Parsing of Iso-8601 Date String with Date.Parse

JavaScript: Which browsers support parsing of ISO-8601 Date String with Date.parse

I had this issue today. I found momentjs was a good way of parsing ISO 8601 dates in a cross browser manor.

momentjs can also be used to output the date in a different format.

Is `new Date(string)` reliable in modern browsers, assuming the input is a full ISO 8601 string?

Yes. The format of acceptable Date strings in JavaScript is standardized:

ECMAScript defines a string interchange format for date-times based upon a simplification of the ISO 8601 calendar date extended format. The format is as follows:

    YYYY-MM-DDTHH:mm:ss.sssZ

From ECMAScript current draft under the section heading " Date Time String Format".

This is the only standard for parsing date strings presented in the spec and hence the aim of date libraries will be to format dates into this format before calling new Date or Date.parse. I can't comment on what the "simplification" of the ISO standard is, but the format asked about in the post matches that of the [ECMAScript] standard.

Note the standard continues on to state date only forms

YYYY

YYYY-MM

YYYY-MM-DD

are accepted and that time formats, optionally followed by a UTC offset, of

THH:mm

THH:mm:ss

THH:mm:ss.sss

may be used following the date component.

Parsing ISO 8601 date in Javascript

datejs could parse following, you might want to try out.

Date.parse('1997-07-16T19:20:15')           // ISO 8601 Formats
Date.parse('1997-07-16T19:20:30+01:00') // ISO 8601 with Timezone offset

Edit: Regex version

x = "2011-01-28T19:30:00EST"

MM = ["January", "February","March","April","May","June","July","August","September","October","November", "December"]

xx = x.replace(
/(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):\d{2}(\w{3})/,
function($0,$1,$2,$3,$4,$5,$6){
return MM[$2-1]+" "+$3+", "+$1+" - "+$4%12+":"+$5+(+$4>12?"PM":"AM")+" "+$6
}
)

Result

January 28, 2011 - 7:30PM EST

Edit2: I changed my timezone to EST and now I got following

x = "2011-01-28T19:30:00-05:00"

MM = {Jan:"January", Feb:"February", Mar:"March", Apr:"April", May:"May", Jun:"June", Jul:"July", Aug:"August", Sep:"September", Oct:"October", Nov:"November", Dec:"December"}

xx = String(new Date(x)).replace(
/\w{3} (\w{3}) (\d{2}) (\d{4}) (\d{2}):(\d{2}):[^(]+\(([A-Z]{3})\)/,
function($0,$1,$2,$3,$4,$5,$6){
return MM[$1]+" "+$2+", "+$3+" - "+$4%12+":"+$5+(+$4>12?"PM":"AM")+" "+$6
}
)

return

January 28, 2011 - 7:30PM EST

Basically

String(new Date(x))

return

Fri Jan 28 2011 19:30:00 GMT-0500 (EST)

regex parts just converting above string to your required format.

January 28, 2011 - 7:30PM EST

javascript date.parse difference in chrome and other browsers

Here is a fix for Firefox and IE/Safari (with the help from JavaScript: Which browsers support parsing of ISO-8601 Date String with Date.parse
) :

DEMO

var noOffset = function(s) {
var day= s.slice(0,-5).split(/\D/).map(function(itm){
return parseInt(itm, 10) || 0;
});
day[1]-= 1;
day= new Date(Date.UTC.apply(Date, day));
var offsetString = s.slice(-5)
var offset = parseInt(offsetString,10)/100;
if (offsetString.slice(0,1)=="+") offset*=-1;
day.setHours(day.getHours()+offset);
return day.getTime();
}

From MDN

JavaScript 1.8.5 note

A subset of ISO 8601 formatted date strings can now also be parsed.

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. Timezones in ISO dates are not yet supported, so e.g. "2011-10-10T14:48:00+0200" (with timezone) does not give the intended result yet.

JavaScript ISO 8601 string into Date object

  • The 2014-03-03T... notation is a fancy JavaScript Date Time String Format and expects a time zone. If you don't provide one, it defaults to Z (UTC).

  • The 2014-03-03 18:30:00 notation, however, is just a regular string without an interesting name and, if you don't provide a time zone, it assumes local time.

This info was taken from the MDN article about Date.parse().

Does Javascript/EcmaScript3 support ISO8601 date parsing?

Try this: http://anentropic.wordpress.com/2009/06/25/javascript-iso8601-parser-and-pretty-dates/

Date parsing in javascript is different between safari and chrome

You can't really use Date.parse. I suggest you use: new Date (year, month [, date [, hours [, minutes [, seconds [, ms ] ] ] ] ] )

To split the string you could try

var s = '2011-06-21T14:27:28.593Z';
var a = s.split(/[^0-9]/);
//for (i=0;i<a.length;i++) { alert(a[i]); }
var d=new Date (a[0],a[1]-1,a[2],a[3],a[4],a[5] );
alert(s+ " "+d);

Chrome 66: Date.parse() gives unexpected results for invalid ISO 8601 dates

The JavaScript Date object is happy to handle unit rollover for you, that's all that's going on with the 2018-06-31 example — it's handling the rollover from June 30th to July 1st.

It doesn't do that for the 2018-06-32 example because 32 is an invalid value for the days field (whereas 31 isn't, it's just that June only has 30 days). The spec defines the valid ranges for the parts of the date/time string here, where we can see it says the valid values for the day of the month are 01 to 31 inclusive.


It's probably worth noting that the parsing of that ISO-8601-derived format (it isn't ISO-8601, quite) if you don't include a timezone indicator has a checkered history, sadly. ES5 specified ISO-8601 but got the meaning of the absense of a timezone indicator wrong (it said it should mean UTC, but ISO-8601 says it means local time); then ES2015 tried to fix that, but conforming to ES2016's rules would have broken a substantial amount of real-world code; and so it wasn't stabilized until ES2016, which says: Date-only forms (like yours) without a timezone indicator are UTC, date/time forms without one are local time. (It's been fine for years if you do include a timezone indicator.)

How to parse dates correctly in Javascript?

Here's the explanation from the Date documentation:

Note: parsing of date strings with the Date constructor (and Date.parse, they are equivalent) is strongly discouraged due to browser differences and inconsistencies. Support for RFC 2822 format strings is by convention only. Support for ISO 8601 formats differs in that date-only strings (e.g. "1970-01-01") are treated as UTC, not local.

The parsing happens correctly, but in the second example, the time is treated as UTC, which then turns in Dec 28th in your local time zone.

More infos:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date

ECMAScript 5 Date.parse results for ISO 8601 test cases

According to the ES5 spec, Date.parse will only work with valid ISO 8601 dates. Anything else is implementation dependent (in practice, IE < 9 doesn't work with standard ISO dates, it requires a '/' seperator). So if you feed it an invalid date (such as 2012-11-31) you can get anythying, from 2012-12-01 to an error.

In your tests:

2012-12-31T23:59:60.000Z

should work, though probably not as you expect. Using 60 for seconds indicates a leap second, it isn't equivalent to 24:00:00, only Safari seems to get that right.

Also:

2012-04-04T24:00:00.000Z

should work, it indicates midnight at the end of 4 April, 2012 so Firefox is in error there.

The formats that ES5 implementations should support are in the spec.

Oh, and you should probably also test omission of the 'T' (since it is optional in certain cases that I think include browsers) and different time zones such as:

2012-04-03 23:50:00+10:00
2012-04-03 23:50:00-04:15
2012-04-03 23:50:00+10
20120403T235000+1000

and so on with YYYYDDD and YYYYWwwD formats, though implementations aren't required to support them.



Related Topics



Leave a reply



Submit