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

我正在使用此下拉列表的应用程序存储时区偏移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,我真的没有最简单的选项来将它们转换为时区缩写,我唯一的select以编程方式执行它将按约400时区缩写sorting。 有没有人知道这个名单,这是什么时候,这是什么时候夏时制是什么时候下拉? (我想我需要手动定义这两个列表)

编辑:parsing这个列表下来为每个时区的一个简称,但他们不是“stream行”的。

我的新名单

 [-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 

码:

 $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); 

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

没有这个标准。 时区缩写不由任何人正式协调。 IANA TZDB中使用了一些,但是很多是随机select的。 经常有关于应使用哪种缩写的争论。 例如,查看2013年4月的列表存档中有多less篇关于澳大利亚缩写的post。

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

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

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

重点在于任何你find的时区缩写的列表都是主观的和自以为是的。 没有标准。

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

要这样做。 时区不是一个偏移量,有超过24个。 请阅读时区标记wiki ,特别是标题为“Time Zone!= Offset”的部分。

从您的意见:

我现在意识到这一点,但是我的应用程序逻辑的其余部分已经这样依赖于它了,而且我今天只有完成这个,所以没有时间去改变它。

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

我对硬编码这些数组没有问题,我只是不知道美国以外的热门地区,我想这样的列表已经存在。

说到时区,你不应该硬编码任何东西。 时区规则一直在改变,因为它们是由世界各国的政治家控制的。 IANA时区数据库每年多次发布更新。 在PHP方面, PHP文档明确了目前可用的版本,并且通过PECL的timezonedb处理更新 – 从IANA提取数据。

关于什么是“stream行” – 这也是非常主观的。 TZDB中的区域出于各种原因都在那里。 我所知道的唯一限制这个的地方是Ruby on Rails的ActiveSupport :: TimeZone 。 他们声称有一个“有意义的146个区域的子集”,你可以在该页面的MAPPING常量中看到。 但是他们并没有说他们决定什么过程是有意义的,而且有明显的遗漏。 除非你知道每个用户的位置,否则我不会去决定要限制哪些区域。

如果你之后的东西是TZDB中所有578个区域的下拉列表,你可以尝试以下方法之一:

  • 目前有两次下降。 第一个select一个国家。 第二个在该国内select一个区域。 在PHP中,你可以看到当你调用DateTimeZone::listIdentifiers ,它接受一个可选的$country参数来过滤列表。

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

    Google日历时区设置

  • 使用基于地图的控件,以便用户可以按位置select他们的时区。 这里有很多,但我最喜欢的是这个 JavaScript的。

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

    基于地图的TZ选择器

请注意,虽然这里显示了EDT的TZDB缩写 – 这只是为了方便显示。 在引擎盖下,你正在select一个像America/New_York的值。

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

更新

有一件事我没有从你原来的post中意识到,但你在评论中澄清说,你正在使用它来select一个目标事件时区。 我想我应该首先要求环境。 我从为用户select单个时区而不是某个特定事件的特定时区的angular度来处理这个问题。

所有你真正需要一个事件在正确的时刻是当时的抵消。 所以你可以使用一个下拉式的,就像你在问题中展示的那样 – 但是我会忽略任何区域名称。 从UTC-12:00UTC+14:00 UTC-12:00 ,它将会是一个明显的偏移列表。 看起来你已经发现了一些30分钟和45分钟的偏移量。 如果你喜欢,你可以在这里validation你的假设。

一般的问题是,很多人不知道抵消应该是什么。 通过列出每个区域名称的标准偏移量,可能会误导用户select错误的偏移量。 例如,他们可能会谈论夏季应该属于美国东部夏令时(-4)的date,但是他们会select-5select,因为他们会看到“东方”。 所以删除名字将有所帮助。

如果按照我原先build议的方式行事,并让他们select实际的IANA时区,那么对于许多情况来说,这种方法将会更好。 但是,还是有一种情况需要考虑 – 如何处理模糊无效的时间。 这些发生在DST转换期间。

例如,我可以selectAmerica/New_York ,并select2013年11月3日凌晨1点。由于后退过渡,有两种不同的情况(EDT中的一个是-4,而另一个是EST -5)。 所以你的应用程序需要检查这一点,并询问用户他们的意思。 同样,如果我在2013年3月10日上午2:00进入,您的应用程序应该告诉我,这个时间在该区域不存在(由于弹簧转换)。

无论采用哪种方法,在实际存储事件时间时,请确保存储date – 时间 – 偏移量组合,或者应用偏移量以获取UTC的date – 时间。 您不希望有任何关于该事件表示实际时刻的问题。