获取时区名称

38

4
可以,new Date() 的输出是 Wed Aug 14 2013 22:02:13 GMT-0700 (Pacific Daylight Time),你需要用它吗? - Ruan Mendes
@ItayItai,您不认为我的答案满足要求吗?这是与OP提供的列表中相同的名称。 - Ruan Mendes
@Juan Mendes:你是对的,但我正在解释使用AJAX来完成这个任务的想法。他可以在服务器端代码方面更加灵活(假设他需要比你的答案更具体的东西)。 - Itay
@Juan Mendes 在 Mac 上的 Safari 中,它不是 Wed Aug 14 2013 22:02:13 GMT-0700(太平洋夏令时),而是像 Wed Aug 14 2013 22:02:13 GMT-0700(PCI)这样。这不是我需要的答案,我需要获取类似于太平洋南美标准时间、格林威治标准时间等时区名称。谢谢您的回复。 - Nathan Nguyễn
@NathanNguyễn,评论和答案中已经提供了足够的信息,让你解决问题,你应该发布你的解决方案。 - Ruan Mendes
显示剩余4条评论
14个回答

53
无法使用 jQuery 获取客户端的时区名称。jQuery 只有一个日期/时间函数 $.now()。如果您指的是 JavaScript,则答案仍然是否定的。您只能从 date.getTimezoneOffset() 获取一个时区的偏移量。至少在某些浏览器中无法获取时区。请参阅时区标签 wiki中的部分标题为:“时区!= 偏移量”。您可以通过使用jsTimeZoneDetect库来猜测用户的时区,但这只是一种猜测,可能准确也可能不准确。您也可以使用moment.jsmoment-timezone添加程序。它现在支持使用moment.tz.guess()进行时区猜测。如果您可以保证您的用户正在运行完全支持ECMAScript 国际化 API 的环境,您可以像这样获取用户的时区:
Intl.DateTimeFormat().resolvedOptions().timeZone

您可以查看兼容性表,在 DateTimeFormat - resolvedOptions().timezone defaults to the host environment 下,以确定这将在哪些环境中起作用。

老实说,最好的方法就是给用户一个屏幕让他们选择自己的时区。 您可以使用下拉列表,也可以使用基于地图的时区选择器 - 像这个。 您可以使用jsTimeZoneDetect作为默认值,但您的用户应该能够更改它。

此外,所有这些都会为您提供IANA时区标识符,例如America / Los_Angeles 。 但是,您提供的示例似乎是Windows时区ID(用于在.NET中使用 TimeZoneInfo )。 您应该阅读时区标签wiki,然后再阅读这个问题:如何在Windows和IANA时区之间进行转换?


@KevalBhatt - 不错!我会记住的,如果有关于时区选择器的问题。这是我给出的那一个不错的替代品。谢谢! - Matt Johnson-Pint
(new Date).toString().split('(')[1].slice(0, -1) - Sami
@Sami - 那不是可靠的。结果可能是任何东西。各个浏览器的实现差异很大,而且没有规范。 - Matt Johnson-Pint
1
有了Intl.DateTimeFormat().resolvedOptions()的兼容性,现在似乎这是最好的选择。谢谢! - T0t3sMcG0t3s

17

new Date() 的输出是 Wed Aug 14 2013 22:02:13 GMT-0700 (Pacific Daylight Time),你能使用吗?如果你不需要正式的名称,你可以只使用括号中的内容。

function getTimeZone() {
    return /\((.*)\)/.exec(new Date().toString())[1];
}

getTimeZone(); // Pacific Daylight Time 

1
在Mac上的Safari中,它不是Wed Aug 14 2013 22:02:13 GMT-0700(太平洋夏令时),而是像Wed Aug 14 2013 22:02:13 GMT-0700(PCI)这样。这不是我需要的答案,我需要获取类似于Pacific S.A. Standard Time,Greenwich Standard Time之类的时区名称。谢谢您的回复。 - Nathan Nguyễn
5
那个回复会高度依赖于浏览器、语言和操作系统的特定环境。 - Matt Johnson-Pint
@MattJohnson 如果你习惯于在自己的操作系统、浏览器和语言中看到自己的时区,并且不需要官方的时区名称,那么这可能是一件好事 :) - Ruan Mendes
如果你想要“太平洋夏令时”而不是“美国/洛杉矶”,这很有帮助。但是@MattJohnson-Pint是正确的,这并不是非常健壮的解决方案。相反,这里有一个与浏览器/语言/操作系统无关的解决方案:https://dev59.com/v2Ml5IYBdhLWcg3woYPa#70376901 - Keavon

14

以下是使用纯JavaScript获取时区的替代方法:

(new Date).toString().split('(')[1].slice(0, -1)

8
获取当前时区的标准名称:

function getTimezoneName() {
    var timeSummer = new Date(Date.UTC(2005, 6, 30, 0, 0, 0, 0));
    var summerOffset = -1 * timeSummer.getTimezoneOffset();
    var timeWinter = new Date(Date.UTC(2005, 12, 30, 0, 0, 0, 0));
    var winterOffset = -1 * timeWinter.getTimezoneOffset();
    var timeZoneHiddenField;

    if (-720 == summerOffset && -720 == winterOffset) { timeZoneHiddenField = 'Dateline Standard Time'; }
    else if (-660 == summerOffset && -660 == winterOffset) { timeZoneHiddenField = 'UTC-11'; }
    else if (-660 == summerOffset && -660 == winterOffset) { timeZoneHiddenField = 'Samoa Standard Time'; }
    else if (-660 == summerOffset && -600 == winterOffset) { timeZoneHiddenField = 'Hawaiian Standard Time'; }
    else if (-570 == summerOffset && -570 == winterOffset) { timeZoneHiddenField.value = 'Pacific/Marquesas'; }
    //                else if (-540 == summerOffset && -600 == winterOffset) { timeZoneHiddenField.value = 'America/Adak'; }
    //                else if (-540 == summerOffset && -540 == winterOffset) { timeZoneHiddenField.value = 'Pacific/Gambier'; }
    else if (-480 == summerOffset && -540 == winterOffset) { timeZoneHiddenField = 'Alaskan Standard Time'; }
    //                else if (-480 == summerOffset && -480 == winterOffset) { timeZoneHiddenField = 'Pacific/Pitcairn'; }
    else if (-420 == summerOffset && -480 == winterOffset) { timeZoneHiddenField = 'Pacific Standard Time'; }
    else if (-420 == summerOffset && -420 == winterOffset) { timeZoneHiddenField = 'US Mountain Standard Time'; }
    else if (-360 == summerOffset && -420 == winterOffset) { timeZoneHiddenField = 'Mountain Standard Time'; }
    else if (-360 == summerOffset && -360 == winterOffset) { timeZoneHiddenField = 'Central America Standard Time'; }
    //                else if (-360 == summerOffset && -300 == winterOffset) { timeZoneHiddenField = 'Pacific/Easter'; }
    else if (-300 == summerOffset && -360 == winterOffset) { timeZoneHiddenField = 'Central Standard Time'; }
    else if (-300 == summerOffset && -300 == winterOffset) { timeZoneHiddenField = 'SA Pacific Standard Time'; }
    else if (-240 == summerOffset && -300 == winterOffset) { timeZoneHiddenField = 'Eastern Standard Time'; }
    else if (-270 == summerOffset && -270 == winterOffset) { timeZoneHiddenField = 'Venezuela Standard Time'; }
    else if (-240 == summerOffset && -240 == winterOffset) { timeZoneHiddenField = 'SA Western Standard Time'; }
    else if (-240 == summerOffset && -180 == winterOffset) { timeZoneHiddenField = 'Central Brazilian Standard Time'; }
    else if (-180 == summerOffset && -240 == winterOffset) { timeZoneHiddenField = 'Atlantic Standard Time'; }
    else if (-180 == summerOffset && -180 == winterOffset) { timeZoneHiddenField = 'Montevideo Standard Time'; }
    else if (-180 == summerOffset && -120 == winterOffset) { timeZoneHiddenField = 'E. South America Standard Time'; }
    else if (-150 == summerOffset && -210 == winterOffset) { timeZoneHiddenField = 'Mid-Atlantic Standard Time'; }
    else if (-120 == summerOffset && -180 == winterOffset) { timeZoneHiddenField = 'America/Godthab'; }
    else if (-120 == summerOffset && -120 == winterOffset) { timeZoneHiddenField = 'SA Eastern Standard Time'; }
    else if (-60 == summerOffset && -60 == winterOffset) { timeZoneHiddenField = 'Cape Verde Standard Time'; }
    else if (0 == summerOffset && -60 == winterOffset) { timeZoneHiddenField = 'Azores Daylight Time'; }
    else if (0 == summerOffset && 0 == winterOffset) { timeZoneHiddenField = 'Morocco Standard Time'; }
    else if (60 == summerOffset && 0 == winterOffset) { timeZoneHiddenField = 'GMT Standard Time'; }
    else if (60 == summerOffset && 60 == winterOffset) { timeZoneHiddenField = 'Africa/Algiers'; }
    else if (60 == summerOffset && 120 == winterOffset) { timeZoneHiddenField = 'Namibia Standard Time'; }
    else if (120 == summerOffset && 60 == winterOffset) { timeZoneHiddenField = 'Central European Standard Time'; }
    else if (120 == summerOffset && 120 == winterOffset) { timeZoneHiddenField = 'South Africa Standard Time'; }
    else if (180 == summerOffset && 120 == winterOffset) { timeZoneHiddenField = 'GTB Standard Time'; }
    else if (180 == summerOffset && 180 == winterOffset) { timeZoneHiddenField = 'E. Africa Standard Time'; }
    else if (240 == summerOffset && 180 == winterOffset) { timeZoneHiddenField = 'Russian Standard Time'; }
    else if (240 == summerOffset && 240 == winterOffset) { timeZoneHiddenField = 'Arabian Standard Time'; }
    else if (270 == summerOffset && 210 == winterOffset) { timeZoneHiddenField = 'Iran Standard Time'; }
    else if (270 == summerOffset && 270 == winterOffset) { timeZoneHiddenField = 'Afghanistan Standard Time'; }
    else if (300 == summerOffset && 240 == winterOffset) { timeZoneHiddenField = 'Pakistan Standard Time'; }
    else if (300 == summerOffset && 300 == winterOffset) { timeZoneHiddenField = 'West Asia Standard Time'; }
    else if (330 == summerOffset && 330 == winterOffset) { timeZoneHiddenField = 'India Standard Time'; }
    else if (345 == summerOffset && 345 == winterOffset) { timeZoneHiddenField = 'Nepal Standard Time'; }
    else if (360 == summerOffset && 300 == winterOffset) { timeZoneHiddenField = 'N. Central Asia Standard Time'; }
    else if (360 == summerOffset && 360 == winterOffset) { timeZoneHiddenField = 'Central Asia Standard Time'; }
    else if (390 == summerOffset && 390 == winterOffset) { timeZoneHiddenField = 'Myanmar Standard Time'; }
    else if (420 == summerOffset && 360 == winterOffset) { timeZoneHiddenField = 'North Asia Standard Time'; }
    else if (420 == summerOffset && 420 == winterOffset) { timeZoneHiddenField = 'SE Asia Standard Time'; }
    else if (480 == summerOffset && 420 == winterOffset) { timeZoneHiddenField = 'North Asia East Standard Time'; }
    else if (480 == summerOffset && 480 == winterOffset) { timeZoneHiddenField = 'China Standard Time'; }
    else if (540 == summerOffset && 480 == winterOffset) { timeZoneHiddenField = 'Yakutsk Standard Time'; }
    else if (540 == summerOffset && 540 == winterOffset) { timeZoneHiddenField = 'Tokyo Standard Time'; }
    else if (570 == summerOffset && 570 == winterOffset) { timeZoneHiddenField = 'Cen. Australia Standard Time'; }
    else if (570 == summerOffset && 630 == winterOffset) { timeZoneHiddenField = 'Australia/Adelaide'; }
    else if (600 == summerOffset && 540 == winterOffset) { timeZoneHiddenField = 'Asia/Yakutsk'; }
    else if (600 == summerOffset && 600 == winterOffset) { timeZoneHiddenField = 'E. Australia Standard Time'; }
    else if (600 == summerOffset && 660 == winterOffset) { timeZoneHiddenField = 'AUS Eastern Standard Time'; }
    else if (630 == summerOffset && 660 == winterOffset) { timeZoneHiddenField = 'Australia/Lord_Howe'; }
    else if (660 == summerOffset && 600 == winterOffset) { timeZoneHiddenField = 'Tasmania Standard Time'; }
    else if (660 == summerOffset && 660 == winterOffset) { timeZoneHiddenField = 'West Pacific Standard Time'; }
    else if (690 == summerOffset && 690 == winterOffset) { timeZoneHiddenField = 'Central Pacific Standard Time'; }
    else if (720 == summerOffset && 660 == winterOffset) { timeZoneHiddenField = 'Magadan Standard Time'; }
    else if (720 == summerOffset && 720 == winterOffset) { timeZoneHiddenField = 'Fiji Standard Time'; }
    else if (720 == summerOffset && 780 == winterOffset) { timeZoneHiddenField = 'New Zealand Standard Time'; }
    else if (765 == summerOffset && 825 == winterOffset) { timeZoneHiddenField = 'Pacific/Chatham'; }
    else if (780 == summerOffset && 780 == winterOffset) { timeZoneHiddenField = 'Tonga Standard Time'; }
    else if (840 == summerOffset && 840 == winterOffset) { timeZoneHiddenField = 'Pacific/Kiritimati'; }
    else { timeZoneHiddenField = 'US/Pacific'; }
    return timeZoneHiddenField;
}

为什么我们需要两个参数(夏令时偏移量,冬令时偏移量)? - NoName
@PhucNguyen 有些时区遵循夏令时,而其他时区则不遵循。 - wjandrea
2
就像宝莱坞电影一样! - ymakux
请注意,巴西不再实行夏令时,因此此信息已过时... https://www.timeanddate.com/time/change/brazil - Ruan Mendes

4

我找到了一个使用moment.js的脚本:

http://pellepim.bitbucket.org/jstz/

这个脚本可以获取浏览器的时区名称,就像这个例子一样:

> var timezone = jstz.determine();
> timezone.name(); 
"America/New_York"

虽然这个功能不在jQuery中,但是...


欢迎来到StackOverflow!仅发布链接而没有相关代码示例并不是非常有帮助的。请尽量避免仅发布链接而没有更多信息。 - Joe McBride
1
很遗憾,这个库不是最新的,因此有些时区可能会被错误地检测到。 - Nikolai Golub

3

使用纯JavaScript和正则表达式:

var d = new Date();
var s = d.toString();
var zoneName = s.match(".*(\\((.*)\\))")[2];

1
无法想到使用Jquery实现的方法。您可以使用PHP获取远程用户的国家名称,然后将输出与以下内容进行比较:
1)适用夏令时的国家数组(不多)。
2)当前日期。

To get the users country:

function visitor_country() {
    $ip = $_SERVER["REMOTE_ADDR"];
    if(filter_var(@$_SERVER['HTTP_X_FORWARDED_FOR'], FILTER_VALIDATE_IP))
            $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
    if(filter_var(@$_SERVER['HTTP_CLIENT_IP'], FILTER_VALIDATE_IP))
            $ip = $_SERVER['HTTP_CLIENT_IP'];
    $result = @json_decode(file_get_contents("http://www.geoplugin.net/json.gp?ip=" . $ip))
            ->geoplugin_countryName;
    return $result <> NULL ? $result : "Unknown";
}
echo visitor_country(); // Output Country name [Ex: United States]
?>

This world Time Zones map link can be used to create the array: http://www.worldtimezone.com/daylight.html

Hope this idea works for you!


1

现代方法

Matt Johnson-Pint的答案提供了IANA时区数据库(tzdata)格式的输出,例如"America/Los_Angeles"

Intl.DateTimeFormat().resolvedOptions().timeZone

// -> "America/Los_Angeles"

console.log(Intl.DateTimeFormat().resolvedOptions().timeZone);

如果您更喜欢时区的确切名称,例如"太平洋标准时间",则可以使用以下表达式:

Intl.DateTimeFormat(undefined, { timeZoneName: "long" })
        .formatToParts(new Date())
        .find((part) => part.type === "timeZoneName").value

// -> "Pacific Standard Time"

console.log(Intl.DateTimeFormat(undefined, { timeZoneName: "long" }).formatToParts(new Date()).find((part) => part.type === "timeZoneName").value);

这应该比Juan Mendes的答案更可靠,因为那种方法是通过精确地匹配(new Date()).toString()的输出来实现的。但是对于使用不同语言、浏览器或操作系统的其他人来说,就没法保证了。上述表达式应该更加稳定。

这在所有现代浏览器中都受到支持,甚至包括Safari。它在Internet Explorer中不起作用。有关更多详细信息,请参见浏览器兼容性图表


1

console.log(Intl.DateTimeFormat().resolvedOptions().timeZone);

Intl.DateTimeFormat().resolvedOptions().timeZone

0

这些链接可能对您有帮助 使用 jQuery 的时区

或者以下代码可能对你有帮助

var offset = (new Date()).getTimezoneOffset();
alert(offset);

请查看JSFiddle的实现,或者如需进一步解释,请访问Solution,作者为Scott

仅限时区

function get_time_zone_offset( ) {
    var current_date = new Date();
  alert(current_date);   
  //return -current_date.getTimezoneOffset() / 60;

}

警告弹出窗口还将显示时区,您可以根据自己的要求进行重构,在JS Fiddle中查看它


1
谢谢您的回复,但我不想获取偏移数字,我想获取时区名称,例如“太平洋南美标准时间,格林威治标准时间”。 - Nathan Nguyễn
@NathanNguyễn,您可以根据您的要求格式化JS Fiddle代码以返回时区名称。 - Digital Alchemist

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接