pytz 和 Etc/GMT-5

发布于 2024-09-28 16:19:26 字数 1023 浏览 9 评论 0原文

我无法理解 pytz 中“Etc/GMT-5”时区和 UTC 之间的转换。

>>> dt = datetime(2009, 9, 9, 10, 0) # September 9 2009, 10:00
>>> gmt_5 = pytz.timezone("Etc/GMT-5")
>>> gmt_5.localize(dt)
datetime.datetime(2009, 9, 9, 10, 0, tzinfo=<StaticTzInfo 'Etc/GMT-5'>)

到目前为止一切都很好,但后来我尝试将其转换为 UTC:

>>> gmt_5.localize(dt).astimezone(pytz.utc)
datetime.datetime(2009, 9, 9, 5, 0, tzinfo=<UTC>)

所以对我来说,似乎当从 GMT-5 中的 10:00 转换为 UTC 时,我得到 05:00?我希望 pytz 会给我 15:00。

我缺少什么?

编辑:我已经确认美国/东部时区的时区转换正如我所期望的那样工作:

>>> eastern = pytz.timezone("US/Eastern")
>>> eastern.localize(dt)
datetime.datetime(2009, 9, 9, 10, 0, tzinfo=...) # Too long
>>> pytz.utc.normalize(eastern.localize(dt).astimezone(pytz.utc))
datetime.datetime(2009, 9, 9, 14, 0, tzinfo=<UTC>)

编辑2:我已经确认当我使用 Etc/GMT+ 时5 我得到 15:00,这是我期望从 Etc/GMT-5 得到的结果。这是 pytz bug 吗?

I'm having trouble understanding the conversion between the "Etc/GMT-5" timezone and UTC in pytz.

>>> dt = datetime(2009, 9, 9, 10, 0) # September 9 2009, 10:00
>>> gmt_5 = pytz.timezone("Etc/GMT-5")
>>> gmt_5.localize(dt)
datetime.datetime(2009, 9, 9, 10, 0, tzinfo=<StaticTzInfo 'Etc/GMT-5'>)

Everything is fine so far, but then I try to convert that to UTC:

>>> gmt_5.localize(dt).astimezone(pytz.utc)
datetime.datetime(2009, 9, 9, 5, 0, tzinfo=<UTC>)

So to me it seems that when converting from 10:00 in GMT-5 to UTC I get 05:00? I would expect pytz to give me 15:00 instead.

What am I missing?

EDIT: I have confirmed that timezone conversion for the US/Eastern timezone works just as I'd expect:

>>> eastern = pytz.timezone("US/Eastern")
>>> eastern.localize(dt)
datetime.datetime(2009, 9, 9, 10, 0, tzinfo=...) # Too long
>>> pytz.utc.normalize(eastern.localize(dt).astimezone(pytz.utc))
datetime.datetime(2009, 9, 9, 14, 0, tzinfo=<UTC>)

EDIT 2: I have confirmed that when I use Etc/GMT+5 I get 15:00, which is what I'd expect to get from Etc/GMT-5. Is this a pytz bug?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

↘人皮目录ツ 2024-10-05 16:19:26

这显然是 POSIX 的事情。来自维基百科

为了符合 POSIX 风格,那些以“Etc/GMT”开头的区域的符号与大多数人期望的相反。在这种样式中,GMT 以西的区域具有正号,而以东的区域具有负号。

This is apparently a POSIX thing. From Wikipedia:

In order to conform with the POSIX style, those zones beginning with "Etc/GMT" have their sign reversed from what most people expect. In this style, zones west of GMT have a positive sign and those east have a negative sign.

晨曦慕雪 2024-10-05 16:19:26

此错误报告解释了此行为。显然他们知道这一切都是颠倒的,但那是因为其他任何东西都会破坏兼容性。

This bug report explains this behavior. Apparently they know that it is all inverted, but that's because anything else would break compatibility.

长安忆 2024-10-05 16:19:26

为什么会出现这种逆转呢?

您观察到的行为是由于 IANA 时区数据库中定义“Etc/GMT-5”时区的方式造成的。 “Etc/GMT-5”时区是 UTC 偏移量的倒置表示,这意味着它表示比 UTC 提前 -5 小时的固定偏移量的时区。

在“Etc/GMT-5”时区中,正偏移量表示时间晚于 UTC,负偏移量表示时间早于 UTC。这与传统的时区表示相反。

当您使用“Etc/GMT-5”时区本地化日期时间 dt 时,您将其设置为 10:00,UTC 偏移量为 -5 小时。因此,在“Etc/GMT-5”时区中,10:00 相当于 UTC 时间 15:00(10:00 - 5 小时)。

但是,当您使用 astimezone (pytz.timezone("UTC")) 方法将此本地化时间转换为 UTC 时,它会考虑原始时区的 UTC 偏移量。由于“Etc/GMT-5”时区的负偏移量为 -5 小时,因此将其转换为 UTC 实际上会在原始时间的基础上增加 5 小时。因此,“Etc/GMT-5”中的 10:00 变为 UTC 中的 05:00(10:00 + 5 小时)。

此行为与 IANA 时区数据库中定义时区的方式一致,其中“Etc/GMT”时区具有反向偏移。

解决方案/解决方法

如果您需要将日期时间从 GMT-5 转换为 UTC 0,您可以使用 pytz 库来处理时区转换。

该策略包括反转 GMT 的符号,也就是说,如果您想要“GMT-5”,那么您将输入“GMT+5”(“Etc/GMT+5”)作为要转换的日期时间时区。

以下是您的操作方法...

from datetime import datetime
import pytz


# Create a datetime object with a GMT-5 timezone.
gmt_minus_5_timezone = pytz.timezone("Etc/GMT+5")
gmt_minus_5_datetime = gmt_minus_5_timezone.localize(datetime(2023, 8, 1, 12, 0, 0))

# Convert the GMT-5 datetime to UTC (UTC+0).
utc_timezone = pytz.timezone("UTC")
utc_datetime = gmt_minus_5_datetime.astimezone(utc_timezone)

print(gmt_minus_5_datetime)
# Output: 2023-08-01 12:00:00-05:00 (Notice the -05:00, which represents GMT-5).

print(utc_datetime)
# Output: 2023-08-01 17:00:00+00:00 (The converted datetime in UTC, which is UTC+0).

谢谢!

Why is this reversal taking place?

The behavior you're observing is because of the way the "Etc/GMT-5" timezone is defined in the IANA Time Zone Database. The "Etc/GMT-5" timezone IS AN INVERTED REPRESENTATION OF THE UTC OFFSET, which means it represents a time zone with a fixed offset of -5 hours ahead of UTC.

In the "Etc/GMT-5" timezone, a positive offset means a time behind UTC, and a negative offset means a time ahead of UTC. This is the opposite of the conventional time zone representation.

When you localize the datetime dt using the "Etc/GMT-5" timezone, you are setting it to 10:00 with a UTC offset of -5 hours. So, in the "Etc/GMT-5" timezone, 10:00 is equivalent to UTC time 15:00 (10:00 - 5 hours).

However, when you convert this localized time to UTC using the astimezone (pytz.timezone("UTC")) method, it takes the UTC offset of the original time zone into account. Since the "Etc/GMT-5" timezone has a negative offset of -5 hours, converting it to UTC effectively adds 5 hours to the original time. So, 10:00 in "Etc/GMT-5" becomes 05:00 in UTC (10:00 + 5 hours).

This BEHAVIOR IS CONSISTENT WITH THE WAY TIME ZONES ARE DEFINED IN THE IANA TIME ZONE DATABASE, where "Etc/GMT" zones have inverted offsets.

Solution/Workaround

If you need to convert a datetime from GMT-5 to UTC 0, you can use the pytz library to handle the time zone conversions.

THE STRATEGY CONSISTS OF INVERTING THE SIGN OF YOUR GMT, that is, if you want "GMT-5" then you will enter "GMT+5" ("Etc/GMT+5") for the datetime timezone you want to convert.

Here's how you can do it...

from datetime import datetime
import pytz


# Create a datetime object with a GMT-5 timezone.
gmt_minus_5_timezone = pytz.timezone("Etc/GMT+5")
gmt_minus_5_datetime = gmt_minus_5_timezone.localize(datetime(2023, 8, 1, 12, 0, 0))

# Convert the GMT-5 datetime to UTC (UTC+0).
utc_timezone = pytz.timezone("UTC")
utc_datetime = gmt_minus_5_datetime.astimezone(utc_timezone)

print(gmt_minus_5_datetime)
# Output: 2023-08-01 12:00:00-05:00 (Notice the -05:00, which represents GMT-5).

print(utc_datetime)
# Output: 2023-08-01 17:00:00+00:00 (The converted datetime in UTC, which is UTC+0).

Thanks! ????

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文