关于php:什么是“标准”时区缩写?

What are the “standard” timezone abbreviations?

对于使用此下拉列表的应用程序,我将按与UTC的偏移量存储时区:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<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个时区缩写进行排序。是否有人知道与此下拉列表一起列出的每个时区是什么,以及夏令时是什么?(我想我需要手动定义这两个列表)

编辑:为每个时区将这个列表解析为一个缩写,但它们不是"流行"的。

我的新名单

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
[-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

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
$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);


What are the"standard" timezone abbreviations?

Ok.

这方面没有标准。时区缩写没有得到任何人的官方协调。在IANA TZDB中有一些应用,但其中很多都是随机选择的。人们经常争论应该使用哪种缩写。例如,看看2013年4月列表档案中有多少关于澳大利亚缩写的帖子。好的。

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

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

另一个很常见的例子是,一些人使用HAST作为夏威夷,而另一些人使用HST,因为他们不太关心阿拉斯加的阿留申群岛(这就是A应该代表的)。好的。

关键是,任何一个时区缩写列表,无论你在哪里找到,都是主观的和固执己见的。没有标准。好的。

I am storing timezone by offset for an application using this dropdown:

Ok.

请不要这样做。时区不是偏移量,其中有24个以上的时区。请阅读时区标签wiki,尤其是标题为"时区!=偏移量。好的。

根据您的评论:好的。

I realize this now, however the rest of my application logic depends on it this way already, and I only have today to complete this, so no time to change it.

Ok.

然后许多错误将继续出现在您的应用程序中。你不能可靠地做到这一点——即使你的应用程序在美国运行也不行。不管您使用的是什么语言或平台,任何这样做的实现都会有很多转换错误。好的。

I'm ok with hardcoding these arrays, I just don't know what the popular zones are outside of the US, I figured such a list would already exist somewhere.

Ok.

说到时区,你不应该硬编码任何东西。时区规则一直在变化,因为它们被世界上每个国家的政治家所控制。每年向IANA时区数据库发布多次更新。在PHP方面,PHP文档清楚地说明了当前可用的版本,并且更新是通过pecl的timezonedb处理的——它从IANA中提取数据。好的。

关于什么是"流行"——这也是非常主观的。由于某种原因,TZDB中的区域都在那里。我知道的唯一一个试图限制这一点的地方是RubyonRails中的ActiveSupport::TimeZone。他们声称拥有"146个区域中有意义的子集",您可以在该页的MAPPING常量中看到。但他们并没有说通过什么过程他们已经决定了什么是有意义的,而且有明显的遗漏。除非你知道你的每一个用户的位置,否则我不会决定限制到哪个区域。好的。

如果您的后续任务不是TZDB中所有578个区域的下拉列表,您可以尝试以下方法之一:好的。

  • 提供两个下拉列表。第一个选择国家。第二个选择那个国家的一个地区。在PHP中,可以看到当调用DateTimeZone::listIdentifiers时,它接受可选的$country参数来过滤列表。好的。

    谷歌日历的设置就是一个很好的例子:好的。

    Google Calendar Time Zone Settings好的。

  • 使用基于地图的控件,以便用户可以按位置选择时区。其中有很多,但我最喜欢的是这一个为javascript。好的。

    例如,它可能如下所示:好的。

    Map-based TZ picker好的。

注意,虽然它在这里显示了EDT的TZDB缩写,但这只是为了方便显示。在引擎盖下,您选择的值类似于America/New_York。好的。

最后,您需要为每个用户保存的是他们的IANA时区键,如America/New_York。您不能只使用-5的值进行正确的时区转换,因为您不具备转换到-4的所有规则。好的。

更新好的。

有一件事我没有从你最初的帖子中意识到,但是你在评论中澄清了,那就是你用这个来选择一个目标事件时区。我想我应该先问一下上下文。我是从为您的用户选择一个时区的角度来处理这个问题的,而不是从特定事件的特定时区。好的。

一个事件在正确的时刻所真正需要的是对那个时刻的抵消。所以你可以使用一个下拉列表,就像你在问题中显示的那样——但是我会省略任何区域名称。从UTC-12:00UTC+14:00的补偿清单几乎没有。看起来您已经确定了大约30分钟和45分钟的偏移量也存在。如果您愿意,可以在这里验证您的假设。好的。

然而,普遍的问题是,许多人不知道补偿应该是什么。通过为每个区域名放置带有标准偏移量的列表,您可能会误导用户选择错误的偏移量。例如,他们可能在谈论一个应该属于美国东部夏令时(-4)的夏季日期,但他们选择-5选项,因为他们看到"东部"。所以删除这些名字会有所帮助。好的。

如果你按照我最初建议的方式去做,让他们选择一个实际的IANA时区,这对于许多场景来说会更好。然而,仍然有一个场景需要考虑——如何处理模糊和无效的时间。这些发生在DST转换期间。好的。

例如,我可以选择America/New_York,并选择2013年11月3日上午1:00。有两种不同的情况是由于后退变(一种在EDT AT-4,另一种在EST AT-5)。所以你的应用程序需要检查这个并询问用户这两者的含义。同样,如果我在2013年3月10日凌晨2:00进入,你的应用程序应该告诉我这个时间不存在于那个区域(由于春运过渡)。好的。

无论采用哪种方法,当涉及到实际存储事件时间时,请确保存储日期-时间偏移组合,或者应用偏移量以获取UTC的日期-时间。你不希望有任何关于事件所代表的实际时间的问题。好的。好啊。