【问题标题】:Time zones `Etc/GMT`, why it is other way round?时区`Etc/GMT`,为什么相反?
【发布时间】:2019-04-04 05:15:40
【问题描述】:

php 中的时区是这样工作的 https://www.gsp.com/support/virtual/admin/unix/tz/gmt/

当它命名为 Etc/GMT+11 时,它实际上是 GMT-11

当它命名为Etc/GMT-11 时,它实际上是GMT+11

为什么? Etc/GMT 是什么意思?

我在 PHP 中找到它,它是 PHP 中的错误还是无处不在?

【问题讨论】:

    标签: timezone timezone-offset


    【解决方案1】:

    这不是错误。 Etc/GMT±* 形式的 tz 数据库标识符故意比我们在 ISO 8601 下预期的通常形式具有倒号。也就是说,它们是在 GMT 以西的正值,而不是在 GMT 以东的正值。

    原因是为了向后兼容 POSIX 样式的时区标识符,例如用于the TZ environment variable 的第一种格式。当 POSIX 兼容系统解释此变量时,America/Los_Angeles 之类的值显然会落入第三种格式(在同一文档中进行了描述),但Etc/GMT+11 之类的值对于应应用哪种格式规则并不明确。因此,区域标识符必须将其符号倒置以符合要求。

    From the tz database where these zones are defined:

    # Be consistent with POSIX TZ settings in the Zone names,
    # even though this is the opposite of what many people expect.
    # POSIX has positive signs west of Greenwich, but many people expect
    # positive signs east of Greenwich.  For example, TZ='Etc/GMT+4' uses
    # the abbreviation "-04" and corresponds to 4 hours behind UT
    # (i.e. west of Greenwich) even though many people would expect it to
    # mean 4 hours ahead of UT (i.e. east of Greenwich).
    

    the Wikipedia article on the tz database 也对此进行了讨论。

    就实际问题而言,tz 数据库评论还说:

    # These entries are mostly present for historical reasons, so that
    # people in areas not otherwise covered by the tz files could "zic -l"
    # to a time zone that was right for their area.  These days, the
    # tz files cover almost all the inhabited world, and the only practical
    # need now for the entries that are not on UTC are for ships at sea
    # that cannot use POSIX TZ settings.
    

    因此,如果您没有为海上船只留出时间,我强烈建议您改用基于位置的标识符。 (也许是Australia/Melbourne?)

    另外,更好的时区标识符来源是the one on Wikipedia

    既然您说您使用的是 PHP,请注意 the PHP documentation has a list as well,并且在 "Others" 页面上,它实际上也解释了这一点:

    警告 请不要使用此处列出的任何时区(UTC 除外),它们仅出于向后兼容的原因而存在,并且可能会暴露错误行为。

    警告 如果您忽略上述警告,还请注意,提供 PHP 时区支持的 IANA 时区数据库使用 POSIX 样式标志,这会导致 Etc/GMT+n 和 Etc/GMT-n 时区与常用时区相反。

    例如,中国和西澳大利亚(以及其他地方)使用的比格林威治标准时间早 8 小时的时区在此数据库中实际上是 Etc/GMT-8,而不是您通常期望的 Etc/GMT+8。

    再次强烈建议您使用适合您所在位置的正确时区,例如上述示例中的亚洲/上海或澳大利亚/珀斯。

    【讨论】:

    • 谢谢。我还发现,在 PHP 中,您可以使用 print_r( DateTimeZone::listIdentifiers() ); 获取“安全”时区列表
    猜你喜欢
    • 2014-06-12
    • 2018-09-29
    • 2019-04-19
    • 2019-11-13
    • 2017-08-31
    • 2020-03-08
    • 1970-01-01
    • 1970-01-01
    • 2020-06-03
    相关资源
    最近更新 更多