带有格式选项的 Intl.DateTimeFormat() 不适用于 'it-CH'



我从服务器获取区域设置,并尝试根据此区域设置格式选项和其他选项格式化给定日期。它适用于所有区域设置,但it-CH

date = new Date(2010,0,1)
new Intl.DateTimeFormat('it-CH', {day:'2-digit', month:'2-digit', year:'numeric'}).format(date)
// output: "01.01.2010"

01/01/2010正确的输出

它适用于区域设置it

new Intl.DateTimeFormat('it', {day:'2-digit', month:'2-digit', year:'numeric'}).format(date)
// output: "01/01/2010"

或者如果我不在选项中包含年份格式,则使用区域设置it-CH

new Intl.DateTimeFormat('it-CH', {day:'2-digit', month:'2-digit'}).format(date)
// output: "01/01"

正确的输出应01/01/2010。我在最新版本的Chrome的Window和Mac OS上对其进行了测试。 这种奇怪的行为从何而来,我该如何解决?

你可以通过使用 intl polyfill 模块来完全替换 NodeJS 的 intl 实现来解决这个问题。

首次运行npm i --save intl

然后你需要用填充物替换国际:

Intl = require("intl")

就是这样。现在您可以尝试:

const date = new Date();
const options = {
year: 'numeric',
day: 'numeric',
month: 'numeric',
hour: 'numeric',
minute: 'numeric'
};
const dateFormatted = new Intl.DateTimeFormat('pt-BR', options).format(date);
console.log(dateFormatted);

预期输出: 24/09/2019 17:43

不幸的是,toLocaleString对日期的实际格式在很大程度上取决于实现,因此虽然它对于最常见的语言和变体可能是一致的,但对于那些不太常见或通常使用多种日期格式的语言和变体(我居住的地方就是这种情况(,它就不是那么好了。

情况相当复杂。"区域设置"是 BCP 47 语言标记。标签和子标签列表由 IANA 维护,并会不时更改。此外,格式到标签和子标签的映射取决于实现。

最重要的是,对于特定语言和变体应适用哪种格式存在不确定性,并且根本不支持大量本地语言和变体(例如部落语言(。因此,不要依赖toLocaleString来完成所有工作并始终正确处理。

将全部留给实现的另一种方法是使用toLocaleString以明确格式手动设置日期格式,以用于各个组件的语言。这样,在不支持特定语言的情况下,您可以回退到浏览器默认语言(请参阅下面的 PPS(,并确信您放在页面上的内容是清晰的,而不是完全将其留给实现,例如

function getFormattedDate(d, lang){
return d.getDate().toLocaleString(lang) + ' '
+ d.toLocaleString(lang, {month:'long'}) + ', '
+ d.toLocaleString(lang, {year:'numeric'});
}
var d = new Date();
['it-CH', 'en-GB', 'ar-EG', 'zu-ZA', 'hz', undefined].forEach(
lang => console.log((lang||'Default') +
': ' + getFormattedDate(d, lang))
);

不要太纠结于支持每种可能的格式和语言变体。确保日期明确比组件是否用逗号、破折号、斜杠或本地变体通常使用的任何内容分隔要重要得多。当我查看我所在地区的正式通信时,日期以 3 或 4 种不同的格式表示,通常在同一页面上使用两种不同的格式(例如在标题、文本和表格数据中(。

PS:在使用之前,您还应该测试对toLocaleString的支持。

PPS:如果有一种方法可以在使用语言标签之前测试是否支持它,那就太好了,但据我所知,这是不可能的。 例如,在上面的例子中,"hz"是赫雷罗语,一种由南部非洲特定民族使用的语言,可能不受任何浏览器的支持, 所以它应该回退到浏览器默认语言。

最新更新