小编典典

什么是“标准”时区缩写?

php

我正在使用此下拉列表按UTC偏移量存储时区:

<select id="timezone" name="timezone" >
<option value="-12">[UTC - 12] Baker Island Time</option>
<option value="-11">[UTC - 11] Niue Time, Samoa Standard Time</option>
<option value="-10">[UTC - 10] Hawaii-Aleutian Standard Time, Cook Island Time</option>
<option value="-9.5">[UTC - 9:30] Marquesas Islands Time</option>
<option value="-9">[UTC - 9] Alaska Standard Time, Gambier Island Time</option>
<option value="-8">[UTC - 8] Pacific Standard Time</option>
<option value="-7">[UTC - 7] Mountain Standard Time</option>
<option value="-6">[UTC - 6] Central Standard Time</option>
<option value="-5">[UTC - 5] Eastern Standard Time</option>
<option value="-4.5">[UTC - 4:30] Venezuelan Standard Time</option>
<option value="-4">[UTC - 4] Atlantic Standard Time</option>
<option value="-3.5">[UTC - 3:30] Newfoundland Standard Time</option>
<option value="-3">[UTC - 3] Amazon Standard Time, Central Greenland Time</option>
<option value="-2">[UTC - 2] Fernando de Noronha Time, South Georgia &amp; the South Sandwich Islands Time</option>
<option value="-1">[UTC - 1] Azores Standard Time, Cape Verde Time, Eastern Greenland Time</option>
<option value="0">[UTC] Western European Time, Greenwich Mean Time</option>
<option value="1">[UTC + 1] Central European Time, West African Time</option>
<option value="2">[UTC + 2] Eastern European Time, Central African Time</option>
<option value="3">[UTC + 3] Moscow Standard Time, Eastern African Time</option>
<option value="3.5">[UTC + 3:30] Iran Standard Time</option>
<option value="4">[UTC + 4] Gulf Standard Time, Samara Standard Time</option>
<option value="4.5">[UTC + 4:30] Afghanistan Time</option>
<option value="5">[UTC + 5] Pakistan Standard Time, Yekaterinburg Standard Time</option>
<option value="5.5">[UTC + 5:30] Indian Standard Time, Sri Lanka Time</option>
<option value="5.75">[UTC + 5:45] Nepal Time</option>
<option value="6">[UTC + 6] Bangladesh Time, Bhutan Time, Novosibirsk Standard Time</option>
<option value="6.5">[UTC + 6:30] Cocos Islands Time, Myanmar Time</option>
<option value="7">[UTC + 7] Indochina Time, Krasnoyarsk Standard Time</option>
<option value="8">[UTC + 8] Chinese Standard Time, Australian Western Standard Time, Irkutsk Standard Time</option>
<option value="8.75">[UTC + 8:45] Southeastern Western Australia Standard Time</option>
<option value="9">[UTC + 9] Japan Standard Time, Korea Standard Time, Chita Standard Time</option>
<option value="9.5">[UTC + 9:30] Australian Central Standard Time</option>
<option value="10">[UTC + 10] Australian Eastern Standard Time, Vladivostok Standard Time</option>
<option value="10.5">[UTC + 10:30] Lord Howe Standard Time</option>
<option value="11">[UTC + 11] Solomon Island Time, Magadan Standard Time</option>
<option value="11.5">[UTC + 11:30] Norfolk Island Time</option>
<option value="12">[UTC + 12] New Zealand Time, Fiji Time, Kamchatka Standard Time</option>
<option value="12.75">[UTC + 12:45] Chatham Islands Time</option>
<option value="13">[UTC + 13] Tonga Time, Phoenix Islands Time</option>
<option value="14">[UTC + 14] Line Island Time</option>

使用PHP,我实际上没有最简单的选项将它们转换为时区缩写,我唯一以编程方式进行选择的方法是对约400个时区缩写进行排序。有人知道每个时区是什么以及夏时制进行时它们是什么的下拉列表吗?(我假设我需要手动定义两个列表)

编辑:将每个时区的此列表解析为单个缩写,但是它们没有“受欢迎”的缩写。

我的新清单

[-12] => kwat
[-11] => bst
[-10] => ahst
[-9.5] => ckhst
[-9] => ahdt
[-8] => akdt
[-7] => east
[-6] => cst
[-5] => act
[-4.5] => ant
[-4] => acst
[-3.5] => negt
[-3] => adt
[-2] => addt
[-1] => azost
[-0] => azomt
[1] => bst
[2] => bdst
[3] => amt
[3.5] => irst
[4] => adt
[4.5] => aft
[5] => aktt
[5.5] => ist
[5.75] => npt
[6] => aktst
[6.5] => burt
[7] => almst
[8] => bnt
[8.75] => cwst
[9] => cdt
[9.5] => cast
[10] => chost
[10.5] => cst
[11] => anat
[11.5] => lhst
[12] => anast
[12.75] => chast
[13] => anast
[14] => anast

Code:

$abbr = DateTimeZone::listAbbreviations();

$offsets=array('-12','-11','-10','-9.5','-9','-8','-7','-6',
    '-5','-4.5','-4','-3.5','-3','-2','-1','-0','1','2','3','3.5',
    '4','4.5','5','5.5','5.75','6','6.5','7','8','8.75','9','9.5',
    '10','10.5','11','11.5','12','12.75','13','14');
$new = array();
$count = 0;
$found = false;
while($count < count($offsets))
{
    foreach($abbr as $k => $v)
    {
        foreach($v as $tz)
        {
            if($tz['offset'] == $offsets[$count]*3600)
            {
                $new[$offsets[$count]] = $k;
                $found = true;
                break;
            }
        }
        if($found)
        {
            $found = false;
            break;
        }
    }
    $count++;
}
print_r($new);

阅读 447

收藏
2020-05-26

共1个答案

小编典典

什么是“标准”时区缩写?

没有为此的标准。时区缩写没有任何人正式协调。IANA TZDB中使用了一些,但是很多是随机选择的。经常有关于使用哪个缩写的争论。例如,在2013年4月的列表档案中,查看有多少篇有关澳大利亚缩写的文章。

可以在此处找到时区缩写的另一个列表。如果仔细观察,您会发现其中很多都是模棱两可的。例如,CST可以是“中央标准时间”(美国),“中国标准时间”或“古巴标准时间”。 EST可以是“东部标准时间”(美国)或“东部标准时间”(澳大利亚)。

一些非澳大利亚人可能更喜欢AEST,但谁又说那A应该是澳大利亚而不是美国?

另一个非常常见的例子是,有些人用HAST在夏威夷,而另一些人用,HST因为他们可能不太在意阿拉斯加的阿留申群岛(这就是该岛所A代表的意思)。

关键是,时区缩写的任何列表(无论您在哪里找到的任何列表)都将是主观的和有根据的。没有标准。

我正在使用此下拉列表按偏移量存储时区:

请不要那样做。时区不是偏移量,其中有24个以上。请阅读时区标签wiki,尤其是标题为“时区!=偏移”的部分。

根据您的评论:

我现在意识到了这一点,但是我的应用程序逻辑的其余部分已经以此方式依赖于此,并且我今天只能完成它,因此没有时间对其进行更改。

然后,您的应用程序中将继续出现许多错误。您只是不能可靠地做到这一点-即使您的应用程序仅在美国运行也不行。不管使用哪种语言或平台,执行此操作的任何实现都会有很多转换错误。

我可以对这些数组进行硬编码,但是我不知道美国以外的流行区域,我认为这样的列表已经存在于某个地方。

说到时区,您不应该硬编码任何东西。时区规则始终在变化,因为它们受世界每个国家/地区的政客控制。每年都会向IANA时区数据库发布多次更新。在PHP方面,PHP文档明确说明了当前可用的版本,并且更新是通过PECL的timezonedb处理的 -它从IANA提取数据。

关于什么是“流行”-这也是高度主观的。TZDB中的区域全部出于一个或另一个原因而存在。我知道唯一尝试限制它的地方是Ruby on Rails的ActiveSupport :: TimeZone。他们声称拥有“ 146个区域的有意义的子集”,您可以MAPPING在该页面的常量中看到。但是他们没有说他们通过什么程序决定了什么才是有意义的,并且有明显的遗漏。除非您知道每个用户的位置,否则我不会尝试确定要限制在哪个区域。

如果除了TZDB中所有578个区域的下拉列表以外,您还可以尝试以下方法之一:

目前有两个下拉列表。第一个选择国家。第二个选择那个国家内的区域。在PHP中,您可以看到在调用时DateTimeZone::listIdentifiers,它接受一个可选$country参数来过滤列表。

Google日历的设置就是一个很好的例子:

Google日历时区设置

使用基于地图的控件,以便您的用户可以按位置选择他们的时区。其中有很多,但是我最喜欢的是这个 JavaScript版本。

例如,它可能看起来像这样:

基于地图的TZ选择器

请注意,尽管它显示的是TZDB的缩写EDT-只是为了显示方便。在后台,您选择的值是America/New_York。

最终,您需要为每个用户保存的是他们的IANA时区密钥,例如America/New_York。您无法仅使用值进行正确的时区转换-5,因为您没有何时切换到的所有规则-4。

更新资料

从您的原始帖子中我没有意识到的一件事,但是您在评论中得到了澄清,那就是您正在使用它来选择目标事件时区。我想我应该先问一下背景。我是从为您的用户选择一个时区而不是为某个特定事件选择特定时区的角度来解决这个问题的。

所有你真的需要一个事件是在正确的时刻是为那一刻的偏移。因此,您可以像在问题中显示的那样使用下拉菜单-但我会省略任何区域名称。后来将是从UTC-12:00到的偏移量列表UTC+14:00。您似乎已经确定存在30分钟和45分钟的偏移量。如果愿意,您可以在此处验证您的假设。

但是,普遍的问题是许多人不知道偏移量应该是多少。通过为每个区域名称放置一个具有标准偏移量的列表,您可能会误导用户选择错误的偏移量。例如,他们可能正在谈论应该在美国东部夏令时(-4)的夏季某个日期,但是他们选择了-5选项,因为它们看到的是“东部”。因此,删除名称会有所帮助。

如果按照我最初建议的方式进行操作,并让他们选择实际的IANA时区,则在许多情况下效果会更好。但是,您仍然需要考虑一种情况-如何处理模棱两可和无效的时间。这些发生在DST过渡期间。

例如,我可能选择America/New_York,然后选择2013年11月3日凌晨1:00的时间。由于回退过渡,有两种不同的实例(一种在EDT中为-4,另一种在EST中为-5) 。因此,您的应用程序需要进行检查,并询问用户这两个含义中的哪一个。同样,如果我在2013年3月10日输入2:00 AM,则您的应用应该告诉我该时间在该区域中不存在(由于spring向前过渡)。

无论使用哪种方法,当涉及到实际存储事件时间时,请确保您存储了date-time-offset组合,或者应用了offset以获取UTC的日期时间。您不希望该事件代表什么实际时间。

2020-05-26