使用Intl.DateTimeFormat获取ISO 8601

时间:2014-07-31 02:42:33

标签: javascript localization

我想使用Intl.DateTimeFormat格式化日期,并在示例中说明

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

很好,所以我希望我的后备是 ISO 8601 ,如果语言不存在

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

然而

//  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

这似乎是因为iso8601不是

的一部分
  

locales带有 BCP 47 语言标记的字符串,或此类字符串的数组。

我也试过使用我所知道的作品,例如:带有en-GB后缀的u-ca-iso8601但如果没有后缀,则不会产生任何不同的结果

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

为什么这不起作用?是否有locale会给我输出我想要的输出?


我宁愿不必使用例如

编写一些复杂的包装器
if (Intl.DateTimeFormat.supportedLocalesOf(['foo']).length === 0)

2 个答案:

答案 0 :(得分:3)

由于似乎没有办法在Intl中自定义区域设置的定义,因此您需要找到使用ISO 8601格式的区域设置。检查By-Type Chart: Date & Time:Gregorian中yMd格式的CLDR定义,我发现了一些类似于ISO 8601.但是,不保证在浏览器或其他JavaScript实现中支持特定的语言环境。

实际上,在CLDR中的这种语言环境中,fo(法罗语)似乎最接近ISO 8601并受浏览器支持。使用Intl.DateTimeFormat(['foo', 'iso8601'], o)进行测试会得到以下结果:

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

因此,Chrome并未完全应用正确的(根据CLDR)格式,并且所有这些浏览器都使用空格而不是T作为分隔符。然而,这个空间使得演示更具可读性,现在它已被接受为现有的ISO 8601,即ISO 8601:2004,它说,

  

4.3.2注意:在信息交换中的合作伙伴的共同协议中,在没有将日期和时间表示与本国际标准中定义的其他人混淆的风险的应用程序中,可省略字符[T]。

然而,在问题中使用包装似乎更安全;与使用某些选定区域设置的风险和kludgy性质相比,它并不太复杂。 (即使所有实现都支持fo,也无法保证法罗语权威机构不会决定必须更改语言环境定义。)

答案 1 :(得分:0)

几年后,我发现基于'fo'或'foo'(Faroese)语言环境的公认答案不再有效。也许正是Jukka推测的那样:法罗群岛当局决定改用(d / m / y)或更正其区域设置信息。

不幸的是,仍然没有添加建议的显式'ISO8601'语言环境,因此即使发生这种情况也相去甚远。

对于@felixbuenemann的评论,我有些困惑,Node 10 does not support locale data只是给出了“ en-us”结果(也许这是Node的自定义版本)。

但是我同意加拿大语言环境(“ fr-CA”和“ en-CA”)是很好的替代品-关键是使用加拿大或瑞典这样的语言环境(已采用ISO 8601),因此语言环境格式为改变的可能性很小。瑞典(sv_SE)实际上比加拿大更好,因为它没有添加非标准逗号,并且使用了更多一致的时区标识符。

所以,我的建议是

new Date().toLocaleString( 'sv_SE', o );
// where the options 'o' is defined as in the question or however you want 

产生“ 2019-09-03 05:29:54”。注意,用空格定界符代替“ T”也是符合标准的。除非您通过将timeZone选项设置为GMT来覆盖本地时间,否则请不要在末尾附加“ Z”(如在问题中所示)。