php - "standard"时区缩写是什么?

标签 php time timezone utc gmt

我正在通过 offset-from-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

代码:
$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?



对此没有标准。时区缩写不是由任何人正式协调的。在IANA TZDB中使用了一些,但其中很多只是随机选择的。关于应该使用哪些缩写,经常有争论。例如,看看有多少关于澳大利亚缩写的帖子in the list archives for April 2013 .

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

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

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

关键是任何时区缩写列表,无论您在何处找到,都将是主观的和自以为是的。没有标准。

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



请不要那样做。时区不是偏移量,它们的数量远远超过 24 个。请阅读 the timezone tag 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.



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

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.



当涉及到时区时,您不应该对任何内容进行硬编码。时区规则一直在变化,因为它们由世界上每个国家的政治家控制。 IANA time zone database 每年都会发布多次更新。 .在 PHP 方面,PHP documentation明确当前可用的版本,以及更新通过 PECL's timezonedb 处理- 从 IANA 中提取数据。

关于什么是“流行的”——这也是非常主观的。 TZDB 中的区域出于某种原因或另一种原因都在那里。我所知道的唯一试图限制这种情况的地方是 ActiveSupport::TimeZone来自 Ruby on Rails。他们声称拥有“有意义的 146 个区域子集”,您可以在 MAPPING 中看到。该页面上的常量。但他们没有说他们通过什么过程决定了什么被认为是有意义的,并且有明显的遗漏。除非您知道每个用户所在的位置,否则我不会尝试决定要限制到哪些区域。

如果您想要的不是 TZDB 中所有 578 个区域的下拉列表,您可以尝试以下方法之一:
  • 呈现两个下拉菜单。首先选择一个国家。第二个选择该国家/地区内的区域。在PHP中,调用 DateTimeZone::listIdentifiers 时可以看到,它接受一个可选的 $country用于过滤列表的参数。

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

    Google Calendar Time Zone Settings
  • 使用基于 map 的控件,以便您的用户可以按位置选择他们的时区。有很多这样的,但我最喜欢的是 this one对于 JavaScript。

    例如,它可能如下所示:

    Map-based TZ picker

  • 请注意,虽然它显示了 EDT 的 TZDB 缩写这里 - 这只是为了方便显示。在幕后,您选择了一个类似 America/New_York 的值。 .

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

    更新

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

    要让事件发生在正确的时刻,您真正需要的只是那个时刻的偏移量。所以你可以使用你在问题中显示的下拉菜单 - 但我会省略任何区域名称。它实际上是来自 UTC-12:00 的偏移量列表至 UTC+14:00 .看起来您已经确定还存在一些 30 分钟和 45 分钟的偏移。您可以验证您的假设 here如果你喜欢。

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

    如果你按照我最初建议的方式让他们选择一个实际的 IANA 时区,这对于许多场景来说会更好。但是,您仍然需要考虑一种情况 - 如何处理模棱两可和无效的时间。这些发生在 DST 转换期间。

    例如,我可能会选择 America/New_York ,并选择 2013 年 11 月 3 日凌晨 1:00 的时间。由于回退过渡,有两个不同的实例(一个在 EDT 的 -4 和另一个在 EST 的 -5)。因此,您的应用程序需要检查这一点并询问用户他们的意思是两者中的哪一个。同样,如果我输入 2013 年 3 月 10 日凌晨 2:00,您的应用程序应该告诉我该时间不存在于该区域(由于 Spring 向前过渡)。

    无论使用哪种方法,当涉及到实际存储事件时间时,请确保您要么存储日期-时间-偏移量组合,要么应用偏移量来获取 UTC 的日期-时间。您不希望对事件代表的实际时间有任何疑问。

    关于php - "standard"时区缩写是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18405262/

    相关文章:

    php - 我在 mysql 查询中的 SQL 语法有什么问题?

    android - 更改时间后获取上一个(旧)时间

    ruby-on-rails - Rails 一天 12 小时 AM/PM 范围

    iphone - iOS 上的当前系统时间

    apache-spark - 带有时区偏移的时间戳

    docker - Debian的zic缺少-b选项

    Python 时间老化,第 2 部分 : timezones

    php - 仅在 IE 中的 CSS 问题

    php - 使用提交按钮通过 PHP 将条目插入 MySQL 数据库?

    php - 如何使 APC(PHP 缓存)工作?