使用 javascript 检测用户的计算机是否使用 12 小时时钟(上午/下午)或 24 小时时钟(军用时间)

问题描述 投票:0回答:6

是否可以检测用户的机器是否使用 12 小时制(上午/下午)或 24 小时制(军用时间)?

一种方法是检查用户区域设置,但这只是区域设置比较的大量列表,来自美国的想要 12 小时时钟的人可以只向我发送区域设置,而不是 US_en,我无法知道她的偏好。同时,来自美国的某人可能将她的机器设置为使用 12 小时时间格式,并且不想要 12 小时时钟。

编辑:

date.toLocaleTimeString();

理论上可行,正如用户 Mouser 在下面建议的那样,但不幸的是,它在 WebKit 浏览器上存在bug(在 Windows 上的 Chrome 和新 Opera 上进行了测试),并且由于某种原因总是返回上午/下午时间。

示例:http://jsfiddle.net/sjuaL3p4/

所以,如果有人知道如何在 webkit 浏览器上完成它,我想我必须重新表述我的问题。

javascript date time webkit clock
6个回答
12
投票

您可以使用国际化 API 和

resolvedOptions
来确定
hourCycle
:

const locale = navigator.language
Intl.DateTimeFormat(locale,  { hour: 'numeric' }).resolvedOptions().hour12 // ?
Intl.DateTimeFormat('en-US', { hour: 'numeric' }).resolvedOptions().hour12 // true
Intl.DateTimeFormat('en-GB', { hour: 'numeric' }).resolvedOptions().hour12 // false

8
投票

此解决方案适用于大多数浏览器,但在 Chrome 中存在错误。

    var date = new Date(Date.UTC(2012, 11, 12, 3, 0, 0));
    var dateString = date.toLocaleTimeString();

    //apparently toLocaleTimeString() has a bug in Chrome. toString() however returns 12/24 hour formats. If one of two contains AM/PM execute 12 hour coding.
    if (dateString.match(/am|pm/i) || date.toString().match(/am|pm/i) )
    {
        //12 hour clock
        console.log("12 hour");
    }
    else
    {
        //24 hour clock
        console.log("24 hour");
    }

Chrome 解决方法;概念证明

对于 Chrome 来说,这是一个丑陋的解决方法。它通过

country_code
嗅出用户
reverse geolocation
。该代码会根据使用 12 小时制的国家/地区的数组进行检查。这个解决方案很丑陋,因为您需要用户权限才能获取地理位置数据,如果用户区域设置不同,它会提供错误的信息,但会为您提供用户的国家/地区。 我强烈建议不要使用这个例子。这纯粹是为了灵感的目的。我将其作为概念证明。

	function getClockChrome() {

		navigator.geolocation.getCurrentPosition(function(pos) {
			var url = "http://nominatim.openstreetmap.org/reverse?format=json&lat="+pos.coords.latitude+"&lon="+pos.coords.longitude+"&addressdetails=1&accept-language=en_US&json_callback=chromeClockCallBack";
			var script = document.createElement('script');
			script.src = url;
			document.body.appendChild(script);
		},
		
		function()
		{
			//no access to location
		},
		

		{
		  enableHighAccuracy: true,
		  timeout: 5000,
		  maximumAge: 0
		}
		);

	}

	getClockChrome();

	var dateCountryCode = ['US', 'GB', 'PH', 'CA', 'AU', 'NZ', 'IN', 'EG', 'SA', 'CO', 'PK', 'MY'];
	function chromeClockCallBack(data)
	{
        //Request succeeded
		if (dateCountryCode.indexOf(data.address.country_code.toUpperCase()) > -1)
		{
			alert("12 hour clock");
		}
		else
		{
			alert("24 hour clock");
		}
	}


2
投票

toLocaleTimeString
should 以反映用户偏好的格式给出时间,但它不可靠。

我使用的是 Debian 系统。

locale
的输出是:

LANG=en_US.utf8
LANGUAGE=
LC_CTYPE="en_US.utf8"
LC_NUMERIC="en_US.utf8"
LC_TIME="en_US.utf8"
LC_COLLATE="en_US.utf8"
LC_MONETARY="en_US.utf8"
LC_MESSAGES="en_US.utf8"
LC_PAPER="en_US.utf8"
LC_NAME="en_US.utf8"
LC_ADDRESS="en_US.utf8"
LC_TELEPHONE="en_US.utf8"
LC_MEASUREMENT="en_US.utf8"
LC_IDENTIFICATION="en_US.utf8"
LC_ALL=

这里有一些

date
的实验:

$ date +%X
05:23:32 PM
$ LANG=en_GB date +%X
17:24:06
$ LC_TIME=en_GB date +%X
17:24:22

%X
格式告诉
date
根据区域设置输出时间。上面的结果完全符合预期。设置
LC_TIME
是一种仅更改时间格式但保持语言环境中其他所有内容不变的方法。因此,即使
en_US
的默认值是 12,美国的某人也可以使用 24 小时时间格式。

我在我的系统上尝试了Mouser的脚本

$ firefox --no-remote
[Shows a time in the 12 hour format, as expected.]
$ LANG=en_GB firefox --no-remote
[Shows a time in the 24 hour format, as expected.]

到目前为止一切顺利。然而,

$ LC_TIME=en_GB firefox --no-remote
[Shows a time in the 12 hour format, this is wrong!]

我使用 Chrome 得到了相同的结果。看来 Firefox 和 Chrome 都忽略了

LC_TIME


1
投票

除了这个永远不应该这样做这一事实之外,即使它确实可以跨浏览器工作,

.toLocaleTimeString()
也不是一个好的解决方案。它返回一个遵循用户计算机设置的格式的时间字符串,但可能有一个仍显示 AM/PM 的 24 小时时钟,也可能有一个不显示 AM/PM 的 12 小时时钟。准确或可靠地检测这一点是不可行的。


0
投票

这条简单的路线似乎对我有用。

var is24 = ((new Date(2014, 01, 01, 15, 0, 0, 0)).toLocaleTimeString().indexOf("15") > -1);

虽然它仍然无法在 Chrome 中运行(在 IE 和 Firefox 中可以运行)


0
投票

这在 Chrome 中对我有用。我使用了 @Mouser 中选定的答案,该答案在 Chrome 中不起作用。

    let result = false;
    const date = new Date();
    const dateString = date.toLocaleTimeString(language, {
        timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone,
        timeStyle: 'short'
    });
    
    if (dateString.match(/am|pm/i) || date.toString().match(/am|pm/i)) {
        result = true;
    }
    else {
        result = false;
    }
© www.soinside.com 2019 - 2024. All rights reserved.