Javascript - 检测用户的区域设置是否设置为使用12小时或24小时时间格式

bri*_*out 11 javascript locale localization google-chrome chromium

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

我强调,我正在寻找一种只有客户端的解决方案,并且它在铬中起作用.

bri*_*out 5

只要铬不能固定,铬就无法toLocaleString()做到这一点.

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

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

  • 不幸的是,Chrome 似乎并不尊重用户对 24 小时时间的偏好——我并排使用 Chrome 和 Safari,而 Safari 正确反映了 24 小时时间,而 Chrome 使用的是 12 小时时间。 (2认同)

Her*_*key 5

自从上次回答这个问题已经有几年了,并且已经引入了一些技术来解决这个问题。一种这样的技术是Intl.DateTimeFormat,它提供了有关各种语言环境的日期格式的丰富信息。

console.log(new Intl.DateTimeFormat().resolvedOptions());
console.log(new Intl.DateTimeFormat().resolvedOptions().hour12);
Run Code Online (Sandbox Code Playgroud)
.as-console-wrapper { max-height: 100% !important; }
Run Code Online (Sandbox Code Playgroud)

但是,大多数语言环境没有为该hour12选项定义默认值。因此,如果返回undefined,我会查看该formatToParts函数。

const hourParts = new Intl.DateTimeFormat(undefined, { hour: 'numeric' }).formatToParts(new Date(2020, 0, 1, 13));
console.log(hourParts);
Run Code Online (Sandbox Code Playgroud)
.as-console-wrapper { max-height: 100% !important; }
Run Code Online (Sandbox Code Playgroud)

输出应该如下所示(对于您浏览器的当前语言;在我的情况下,“en-US”):

[
  {
    "type": "hour",
    "value": "1"
  },
  {
    "type": "literal",
    "value": " "
  },
  {
    "type": "dayPeriod",
    "value": "PM"
  }
]
Run Code Online (Sandbox Code Playgroud)

得到value零件的长度type等于"hour"会告诉你是否有十二或24小时时间格式化。

例如,我碰巧知道在日本,他们使用二十四小时制,所以我可以检查一下:

[
  {
    "type": "hour",
    "value": "1"
  },
  {
    "type": "literal",
    "value": " "
  },
  {
    "type": "dayPeriod",
    "value": "PM"
  }
]
Run Code Online (Sandbox Code Playgroud)
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);
Run Code Online (Sandbox Code Playgroud)

而且我知道美国默认为 12 小时时间:

.as-console-wrapper { max-height: 100% !important; }
Run Code Online (Sandbox Code Playgroud)
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);
Run Code Online (Sandbox Code Playgroud)

将它包装在一个函数中很容易:

.as-console-wrapper { max-height: 100% !important; }
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)

您可能会发现这比解析输出更复杂或更简单 toLocaleString().

注意:我在回答中途从使用术语“语言环境”切换到“语言”。这是由于规范是如何编写的以及信息是如何指定的。en-USja-JP是 BCP 语言代码,传递给的构造函数Intl.DateTimeFormat以查找日期和时间格式规则。本说明书中使用术语locale来指代这片的信息,但实际上它是一种语言标识符,该标识符,而它可包含的区域(USJP在所提到的代码),不要求它们,也没有该区域一定表示用户的locale(考虑一个说西班牙语并在西班牙学习的人[因此会使用语言代码“es-ES”],但住在美国,那里的日期格式与西班牙不同)。