时区 `Etc/GMT`,为什么是反过来的?

12

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的错误还是普遍存在的错误?

1个回答

15
这不是一个bug。形如Etc/GMT±*的时区数据库标识符故意与我们在ISO 8601下期望的常规形式相反。也就是说,它们是以正值表示格林威治时间西侧,而不是以正值表示格林威治时间东侧。
原因是为了向后兼容POSIX风格的时区标识符,例如TZ环境变量的第一种格式中使用的标识符。当POSIX兼容系统解释此变量时,像America/Los_Angeles这样的值显然会落入第三种格式(在同一文档中描述),但像Etc/GMT+11这样的值对于应用哪种格式规则是模棱两可的。因此,时区标识符必须将其符号反转才能符合规范。 这些区域定义在时区数据库中
# 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).

这也在tz数据库的维基百科文章中讨论过。

就实际问题而言,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?)。
另外,更好的时区标识符来源是维基百科上的那个
由于您说您正在使用PHP,请注意PHP文档也有一个列表,在“其他”页面上,它实际上也解释了这一点:

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

警告 如果您忽略上述警告,请注意提供PHP时区支持的IANA时区数据库使用POSIX风格的符号,这导致Etc/GMT+n和Etc/GMT-n时区与常规用法相反。

例如,在中国和西澳大利亚等地使用的比GMT快8小时的时区实际上在该数据库中为Etc/GMT-8,而不是您通常期望的Etc/GMT+8。
再次强烈建议您使用正确的时区,例如上海或珀斯的亚洲/悉尼。

1
谢谢。我还发现在PHP中,您可以使用print_r(DateTimeZone::listIdentifiers());获取“安全”时区列表。 - Yevgeniy Afanasyev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接