Javascript -- 检测用户的语言环境是不是设置为使用 12 小时或 24 小时时间格式

Posted

技术标签:

【中文标题】Javascript -- 检测用户的语言环境是不是设置为使用 12 小时或 24 小时时间格式【英文标题】:Javascript -- Detect if user's locale are set to use 12-hour or 24-hour time formatJavascript -- 检测用户的语言环境是否设置为使用 12 小时或 24 小时时间格式 【发布时间】:2011-09-04 13:27:58 【问题描述】:

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

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

【问题讨论】:

我认为这可能会对您有所帮助 [how-do-i-display-a-date-time-in-the-users-locale-format-and-time-offset][1] [1 ]:***.com/questions/85116/… 做一个男人,为每个人强制24小时! @brillout.com 您接受的答案已过时。请更新此问题并检查 EliGreys 的答案(请注意,有人给了他 100+ 分!) toLocaleString 生成的字符串由相关的语言代码(默认或指定)控制,与语言环境(即地理位置)无关。 【参考方案1】:

自从上次回答这个问题以来已经有几年了,并且已经引入了一些技术来解决这个问题。其中一种技术是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"
  
]

获取具有type 的部分的value 的长度等于"hour" 将告诉您它是用十二小时还是二十四小时时间格式化的。

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

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),但不需要它们,该地区也不一定表示用户的区域设置(考虑一个说西班牙语并在西班牙学习的人[因此会使用语言代码'es-ES'],但居住在美国,日期格式不同比西班牙)。

【讨论】:

谢谢。它非常适合我感兴趣的场景。 "en-US" 不是语言环境,而是语言代码。 ECMA-402 的作者一直使用这种用词不当,确实应该解决。 @RobG 可以肯定的是,它应该得到解决。但是,我不确定处理 Intl 和 ECMA-402 的每个答案都需要修改。确实应该由ECMA处理,然后可以修改答案以匹配。 @HereticMonkey——是的,这取决于作者来修复它。与此同时,错误一直存在……【参考方案2】:

只要 Chromium 不修复 toLocaleString(),就无法在 Chromium 中修复。

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

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

【讨论】:

此答案已过时:已在 Chrome (~ v32) 中修复! 不幸的是,Chrome 似乎不尊重用户对 24 小时制的偏好 - 我正在并排使用 Chrome 和 Safari,而 Safari 正确地反映了 24 小时制,而 Chrome 使用的是 12 小时制。跨度> @agnoster 你确定吗?我在 OSX 设置中将时间显示设置为使用 24 小时制,然后在 Safari 中进行测试,我得到了 12 小时制的时间。 Apple 可能修复了这个错误,因为调用 toLocaleString() 要求将时间格式化为特定的 locale,并遵守系统设置中对 locale 格式的覆盖是不正确的。 @agnoster 我不确定您是否知道,但是遇到此答案的人并不知道它已被修复除非有人指出,我完成了。当您搜索它时,它只是 Google 中的第三个结果,因此指出它很重要。如果您要对此刻薄,请出于正确的理由这样做,而不是因为您的吉米被沙沙作响。另外,我只是在 Chrome 中尝试过,无法获得 24 小时格式。您确定您的 Chrome 的默认语言环境不是 en-US【参考方案3】:

您永远不应该以这种方式搜索本地模式。 toLocaleString() 显然是一个错误(源自 Java),不应使用。正如您所提到的,这种方法在各种浏览器中都没有得到很好的支持(Chrome 只是其中之一)。 事实上,唯一能够正确(但不是 100% 正确)的网络浏览器(来自流行的浏览器)是 IE。

要根据区域设置正确格式化日期,请使用Globalize。它包含从 .Net 中转储的本地化模式。 您可能还想使用Dojo,它也允许区域设置感知格式,但基于CLDR。

编辑,新的事实存在

javascript 中有一个新的 I18n 标准 - ECMA-402。这个标准实际上允许使用 JS Date 的对象。但是,应该始终传递一个语言标签:

var date = new Date();
var formatted = date.toLocaleString('de-DE');

唯一的问题是,我知道当前实现 ECMA-402 的唯一网络浏览器是 Google Chrome。

目前看来,仍然可以使用类似于iLib 的东西。

【讨论】:

感谢有关 toLocaleString 的信息。实际上我只想知道用户的区域设置是使用 12 小时还是 24 小时格式。所以我猜 toLocaleString 可能会为 Firefox 和 IE 完成这项工作。对于 Globalize 和 CLDR,它不起作用,因为 12 小时/24 小时格式与用户区域设置的语言无关 @cept0:很明显,你一定是 I18n 的长期专家。非常抱歉,我保证不再在 I18n 上写任何东西。顺便提一句。在撰写本文时,ECMA-402 还不存在。【参考方案4】:

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

【讨论】:

这不起作用。正如我在 Pawel 的回答中评论的那样,12 小时/24 小时格式与用户区域设置的语言无关。例如。我曾经使用 en-US 但 24 小时格式 对不起,你是少数。仅仅因为某人可以更改默认值并不意味着大多数人可以en-US 和 12 小时格式之间有足够高的相关性,您应该忽略极少数的边缘情况。要么就是这样,要么根本没有解决方案,因为 JavaScript 无法访问操作系统级别的设置。 你说“足够高的相关性”。你有任何统计数据/资料来支持你的说法吗?谢谢 嗯。最后我检查了“更有可能”和“少数边缘情况”在不同的领域;如果您说“忽略使用 24 小时制和英语(美国)的任何人”,您就是忽略了一大群出于商业原因 24 小时使用美国英语的国际用户。更不用说你忽略了军队;-)如果你基本上愿意说“只有生活在美国的平民更喜欢上午/下午的事情”,那么你真的不应该参与本地化/国际化工作;- ) @agnoster 然后由浏览器供应商来实现告诉我们用户的自定义时间设置是什么。此外,“如果不符合标准化语言环境,则根据用户想要的格式进行格式化”这就是toLocaleString() 的重点,不是吗?使用给定语言环境的标准格式来格式化时间?【参考方案5】:

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

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

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

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

【讨论】:

这在 chrome 中不起作用,因为 chrome 总是会返回 13 那么也许,chrome 用户只需要坚持 24 小时?该实现仍然适用于所有其他浏览器,但仅在 chrome 上显示 13!

以上是关于Javascript -- 检测用户的语言环境是不是设置为使用 12 小时或 24 小时时间格式的主要内容,如果未能解决你的问题,请参考以下文章

检测天气用户是不是在反应js和javascript中滚动div的底部

使用 javascript 或 jQuery 检测用户是不是拒绝浏览器定位计算机的请求

如何在javascript中检测浏览器选项卡是不是关闭或浏览器窗口

ASP 注册页面,同步检测用户名是不是已存在

如何在客户端使用 JavaScript 来检测页面是不是已加密?

js javascript浏览器语言检测,获取用户的浏览器语言首选项