Skip to content

Get ISO 8601 using Intl.DateTimeFormat

I want to use Intl.DateTimeFormat to format a Date, and in the examples it says

// when requesting a language that may not be supported, such as
// Balinese, include a fallback language, in this case Indonesian

Great, so I want my fallback to be ISO 8601 in the case a language doesn’t exist

// i.e. the same as/similar to
new Date().toISOString(); // "2014-07-31T02:42:06.702Z"

however

//  Intl.DateTimeFormat([locales [, options]])
var o = {};
o.year = o.month = o.day = o.hour = o.minute = o.second = 'numeric';
new Intl.DateTimeFormat(['foo', 'iso8601'], o);
// RangeError: Invalid language tag: iso8601

This seems to be because iso8601 isn’t part of

locales A string with a BCP 47 language tag, or an array of such strings.

I’ve also tried using one I know works, e.g. en-GB with a u-ca-iso8601 suffix but this doesn’t produce any different result to without the suffix

var f = new Intl.DateTimeFormat(['foo', 'en-GB-u-ca-iso8601'], o);
f.format(new Date());
// 31/7/2014 03:35:26

Why isn’t this working? Is there even a locale which will give me the output I’m looking for?


I’d rather not have to write some complicated wrapper using e.g.

if (Intl.DateTimeFormat.supportedLocalesOf(['foo']).length === 0)

Answer

Since there does not seem to be a way to customize the definitions of locales in Intl, you would need to find a locale that uses an ISO 8601 format. Checking the CLDR definitions for the yMd format in By-Type Chart: Date & Time:Gregorian, I found some that resemble ISO 8601. However, support to specific locales in browsers or other JavaScript implementations is not guaranteed.

In practice, among such locales in CLDR, fo (Faroese) seems to come closest to being ISO 8601 and supported by browsers. Testing with Intl.DateTimeFormat(['foo', 'iso8601'], o) gives the following results:

2014-7-31 10:26:50      in Chrome
2014-07-31 10:26:50     in Firefox and IE

Thus, Chrome does not quite apply the correct (as per CLDR) format, and all of these browsers use a space and not T as a separator. However, the space makes the presentation more readable, and it is now accepted alternative according to current ISO 8601, namely ISO 8601:2004, which says,

4.3.2 NOTE: By mutual agreement of the partners in information interchange, the character [T] may be omitted in applications where there is no risk of confusing a date and time of day representation with others defined in this International Standard.

However, it seems safer to use a wrapper, as in the question; it’s not too complicated, compared with the risks and kludgy nature of using some selected locale. (Even if fo is supported by all implementations, there is no guarantee that Faroese authorities won’t decide that the locale definition must be changed.)