一种方法是解析new Date().toLocaleString()
. 但这在 chromium/webkit 中不起作用,因为它返回的字符串不依赖于用户的语言环境(参见错误报告http://code.google.com/p/chromium/issues/detail?id=3607上的错误报告)
我强调我正在寻找一种仅适用于客户端并且适用于铬的解决方案。
一种方法是解析new Date().toLocaleString()
. 但这在 chromium/webkit 中不起作用,因为它返回的字符串不依赖于用户的语言环境(参见错误报告http://code.google.com/p/chromium/issues/detail?id=3607上的错误报告)
我强调我正在寻找一种仅适用于客户端并且适用于铬的解决方案。
自从上次回答这个问题以来已经有几年了,并且已经引入了一些技术来解决这个问题。一种这样的技术是Intl.DateTimeFormat
,它提供了有关各种语言环境的日期格式的大量信息。
console.log(new Intl.DateTimeFormat().resolvedOptions());
console.log(new Intl.DateTimeFormat().resolvedOptions().hour12);
.as-console-wrapper { max-height: 100% !important; }
但是,大多数语言环境都没有为该hour12
选项定义默认值。所以,如果这返回undefined
,我会看看这个formatToParts
函数。
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”):
[
{
"type": "hour",
"value": "1"
},
{
"type": "literal",
"value": " "
},
{
"type": "dayPeriod",
"value": "PM"
}
]
使用等于获取value
部分的长度将告诉您它是用 12 小时还是 24 小时时间格式化的。type
"hour"
例如,我碰巧知道在日本,他们使用二十四小时的时间,所以我可以检查一下:
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; }
而且我知道美国默认为十二小时时间:
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; }
将它包装在一个函数中很容易:
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()
.
注意:我在回答中途从使用术语“语言环境”切换到“语言”。这是由于规范的编写方式和信息的指定方式。en-US
和ja-JP
是 BCP 语言代码,传递给构造函数Intl.DateTimeFormat
以查找日期和时间格式规则。该规范使用该术语locale
来指代这条信息,但实际上它是一种语言标识符,虽然它可能包含一个区域(在提到US
的JP
代码中),但不需要它们,该区域也不一定表示用户的locale(考虑一个说西班牙语并在西班牙学习的人[因此将使用语言代码'es-ES'],但居住在美国,其日期格式与西班牙不同)。
只要 Chromium 不修复toLocaleString()
,就无法在 Chromium 中做到这一点。
对于 Firefox 和 IE 解析toLocaleString()
将提供该信息。
编辑
显然toLocalString()
现在已在 Chrome 中修复。因此,解析toLocaleString()
是一种解决方案。
您永远不应该以这种方式搜索本地模式。toLocaleString()
显然是一个错误(源自 Java),不应使用。正如您所提到的,这种方法在各种浏览器中都没有得到很好的支持(Chrome 只是其中之一)。
事实上,唯一能够正确(但不是 100% 正确)的网络浏览器(来自流行的浏览器)是 IE。
要根据区域设置正确格式化日期,请使用Globalize。它包含从 .Net 中转储的本地化模式。
您可能还想使用Dojo,它也允许 Locale-aware 格式化,但基于CLDR。
JavaScript 中的 I18n 有一个新标准 - ECMA-402。这个标准实际上允许使用 JSDate
的对象。但是,应该始终传递一个语言标签:
var date = new Date();
var formatted = date.toLocaleString('de-DE');
唯一的问题是,我知道目前实现 ECMA-402 的唯一网络浏览器是 Google Chrome。
目前看来,仍然要走的路是使用类似 iLib 的东西。
解析(new Date).toLocaleString()
除 Chrome 之外的所有浏览器,并检查 Chromenavigator.language
的区域设置地图及其时间格式。
我知道这将是最不受欢迎的方式,但你能不能只检查一下时间?
如果时间在 12 点之前,则将时间设置为下午 1 点,并测试输出是 13 还是 1。
我知道这是一个想法,但如果放入一个不错的 Date.prototype.is24hour() 中,则返回 true;它可以很好地工作吗?
我使用带有日期的http://www.datejs.com/ 。倾向于做我需要的一切!因此,您可以将其与自定义原型函数一起使用,这将为您提供所需的东西!