Javascript -- 检测用户的语言环境是否设置为使用 12 小时或 24 小时时间格式
一种方法是解析 new Date().toLocaleString()
.但这在 chromium/webkit 中不起作用,因为它返回的字符串不依赖于用户的语言环境(请参阅 http://code.google.com/p/chromium/issues/detail?id=3607)
One way to do that is to parse new Date().toLocaleString()
.
But this doesn't work in chromium/webkit since the string it returns isn't dependent of the user's locale (see bug report at http://code.google.com/p/chromium/issues/detail?id=3607)
我强调我正在寻找一种仅适用于客户端且适用于 chromium 的解决方案.
I emphasize that I'm looking for a solution that is client side only and that works in chromium.
推荐答案
距离上次回答这个问题已经有几年了,并且已经引入了一些技术来解决这个问题.一种这样的技术是 Intl.DateTimeFormat
,它提供了有关各种语言环境的日期格式的大量信息.
It's been a few years since this was last answered and a few technologies have been introduced to solve the issue. One such technology is Intl.DateTimeFormat
, which provides a wealth of information about date formats for various locales.
console.log(new Intl.DateTimeFormat().resolvedOptions());
console.log(new Intl.DateTimeFormat().resolvedOptions().hour12);
.as-console-wrapper { max-height: 100% !important; }
但是,大多数语言环境没有为 hour12
选项定义默认值.所以,如果这返回 undefined
,我会查看 formatToParts
函数.
However, most locales don't define a default for the hour12
option. So, if this returns undefined
, I'd look at the formatToParts
function.
const hourParts = new Intl.DateTimeFormat(undefined, { hour: 'numeric' }).formatToParts(new Date(2020, 0, 1, 13));
console.log(hourParts);
.as-console-wrapper { max-height: 100% !important; }
输出应该如下所示(对于您的浏览器的当前语言;在我的例子中,en-US"):
The output from that should look like (for your browser's current language; in my case, "en-US"):
[
{
"type": "hour",
"value": "1"
},
{
"type": "literal",
"value": " "
},
{
"type": "dayPeriod",
"value": "PM"
}
]
获取 type
等于 小时"
部分的 value
的长度将告诉您它是否被格式化为 12或二十四小时制.
Getting the length of the value
of the part with type
equal to "hour"
will tell you whether it was formatted with twelve or twenty-four hour time.
例如,我碰巧知道在日本,他们使用 24 小时制,所以我可以检查一下:
For instance, I happen to know that in Japan, they use twenty four hour time, so I can check that:
const hourParts = new Intl.DateTimeFormat('ja-JP', {
hour: 'numeric'
}).formatToParts(new Date(2020, 0, 1, 13));
console.log(hourParts.find(part => part.type === 'hour').value.length);
.as-console-wrapper { max-height: 100% !important; }
而且我知道美国默认为十二小时时间:
And I know the the US defaults to twelve hour time:
const hourParts = new Intl.DateTimeFormat('en-US', {
hour: 'numeric'
}).formatToParts(new Date(2020, 0, 1, 13));
console.log(hourParts.find(part => part.type === 'hour').value.length);
.as-console-wrapper { max-height: 100% !important; }
将它包装在一个函数中很容易:
It would be easy enough to wrap this in a function:
function localeUses24HourTime(langCode) {
return new Intl.DateTimeFormat(langCode, {
hour: 'numeric'
}).formatToParts(new Date(2020, 0, 1, 13)).find(part => part.type === 'hour').value.length === 2;
}
console.log(localeUses24HourTime()); // undefined means current user's language
console.log(localeUses24HourTime('en-US')); // a specific language known to be false
console.log(localeUses24HourTime('ja-JP')); // a specific language known to be true
.as-console-wrapper { max-height: 100% !important; }
您可能会发现这或多或少比解析 toLocaleString()
的输出复杂.
You may find this more or less complicated than parsing the output of toLocaleString()
.
注意:我不再使用语言环境"一词,而是使用语言环境"一词.到语言"在我的回答中途.这是由于规范的编写方式和信息的指定方式.en-US
和 ja-JP
是 BCP 语言代码,传递给 Intl.DateTimeFormat
的构造函数以查找日期和时间格式规则.规范使用术语 locale
来指代这条信息,但实际上它是一种语言标识符,虽然它可能包含一个区域(US
和 JP
在提到的代码中),不需要它们,该区域也不一定指示用户的语言环境(考虑说西班牙语并在西班牙学习的人[因此将使用语言代码es-ES"],但生活在美国,那里的日期格式与西班牙不同).
Note: I switched from using the term "locale" to "language" midway through my answer. This is due to how the specification is written and how information is specified. en-US
and ja-JP
are BCP language codes, passed to the constructor of Intl.DateTimeFormat
to look up date and time formatting rules. The specification uses the term locale
to refer to this piece of information but indeed it is a language identifier, which, while it may contain a region (the US
and JP
in the mentioned codes), does not require them, nor does that region necessarily indicate the user's locale (consider a person who speaks Spanish and learned it in Spain [and therefore would use the language code 'es-ES'], but lives in the United States, where the dates are formatted differently than in Spain).
相关文章