15

一种方法是解析new Date().toLocaleString(). 但这在 chromium/webkit 中不起作用,因为它返回的字符串不依赖于用户的语言环境(参见错误报告http://code.google.com/p/chromium/issues/detail?id=3607上的错误报告)

我强调我正在寻找一种仅适用于客户端并且适用于铬的解决方案。

4

5 回答 5

8

自从上次回答这个问题以来已经有几年了,并且已经引入了一些技术来解决这个问题。一种这样的技术是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-USja-JP是 BCP 语言代码,传递给构造函数Intl.DateTimeFormat以查找日期和时间格式规则。该规范使用该术语locale来指代这条信息,但实际上它是一种语言标识符,虽然它可能包含一个区域(在提到USJP代码中),但不需要它们,该区域也不一定表示用户的locale(考虑一个说西班牙语并在西班牙学习的人[因此将使用语言代码'es-ES'],但居住在美国,其日期格式与西班牙不同)。

于 2020-02-27T16:21:38.147 回答
5

只要 Chromium 不修复toLocaleString(),就无法在 Chromium 中做到这一点。

对于 Firefox 和 IE 解析toLocaleString()将提供该信息。

编辑
显然toLocalString()现在已在 Chrome 中修复。因此,解析toLocaleString()是一种解决方案。

于 2011-09-30T15:34:15.483 回答
3

您永远不应该以这种方式搜索本地模式。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 的东西

于 2011-09-25T08:11:51.030 回答
2

解析(new Date).toLocaleString()除 Chrome 之外的所有浏览器,并检查 Chromenavigator.language的区域设置地图及其时间格式。

于 2011-09-30T19:52:48.803 回答
1

我知道这将是最不受欢迎的方式,但你能不能只检查一下时间?

如果时间在 12 点之前,则将时间设置为下午 1 点,并测试输出是 13 还是 1。

我知道这是一个想法,但如果放入一个不错的 Date.prototype.is24hour() 中,则返回 true;它可以很好地工作吗?

我使用带有日期的http://www.datejs.com/ 。倾向于做我需要的一切!因此,您可以将其与自定义原型函数一起使用,这将为您提供所需的东西!

于 2011-10-07T13:24:48.413 回答