将日期时间打印为 pytz.timezone("Etc/GMT-5") 会产生不正确的结果

Printing datetime as pytz.timezone("Etc/GMT-5") yields incorrect result

考虑以下示例,我在其中采用简单的日期时间,使其在 UTC 中识别时区,然后转换为 UTC-5:

d1 = datetime.datetime(2019,3,7, 7,45)

d2 = pytz.utc.localize(d1)
print(f'UTC  : {d2}')

d3 = d2.astimezone(pytz.timezone('Etc/GMT-5'))
print(f'UTC-5: {d3}')

这个输出是:

UTC  : 2019-03-07 07:45:00+00:00
UTC-5: 2019-03-07 12:45:00+05:00

我原以为 UTC-5 时间是 02:45,但 5 小时的偏移量是 添加 到 UTC,而不是减去。

问题:

显然,在 posix 风格的系统中,您必须使用时区偏移量的倒数。这意味着如果你想得到 -5,你必须使用 GMT+5

d3 = d2.astimezone(pytz.timezone('Etc/GMT+5'))

打印

UTC-5: 2019-03-07 02:45:00-05:00

否则,您必须将 posix_offset 设为 true。这是在 dateutil 文档中;

There is one notable exception, which is that POSIX-style time zones use an inverted offset format, so normally GMT+3 would be parsed as an offset 3 hours behind GMT. The tzstr time zone object will parse this as an offset 3 hours ahead of GMT. If you would like to maintain the POSIX behavior, pass a True value to posix_offset.

https://dateutil.readthedocs.io/en/stable/tz.html#dateutil.tz.tzstr

您正在使用 pytz,而不仅仅是 Python 的 datetimeLike dateutil, pytz uses the Olson tz database.

Olson tz 数据库定义 Etc/GMT+N 个时区 conform with the POSIX style:

those zone names beginning with "Etc/GMT" have their sign reversed from the standard ISO 8601 convention. In the "Etc" area, zones west of GMT have a positive sign and those east have a negative sign in their name (e.g "Etc/GMT-14" is 14 hours ahead of GMT.)


因此,要将 UTC 转换为偏移量为 -5 的时区,您可以使用 Etc/GMT+5:

import datetime as DT
import pytz

naive = DT.datetime(2019, 3, 7, 7, 45)
utc = pytz.utc
gmt5 = pytz.timezone('Etc/GMT+5')
print(utc.localize(naive).astimezone(gmt5))

# 2019-03-07 02:45:00-05:00