为什么在 Python 的时区之间转换会产生不同的结果?

Why converting between time zones in Python yields different results?

我处理 Python 中的时区已有一段时间了。我的挑战之一是创建一个奖品,该奖品在当前时间之后的几天内在适当的时区 23:59:59 之前有效。我采用了当前的 UTC 时间,添加了一个 timedelta,转换为所需的时区,替换 hour/minutes/seconds 并转换回 UTC。那行得通,现在仍然完美无缺。

最近我试图在另一个项目上重写该代码,但遇到了一个我无法解释的情况。查看下面的示例代码。

from datetime import datetime
import pytz

dt1 = datetime\
.now(pytz.utc)\
.astimezone(pytz.timezone("America/Sao_Paulo"))\
.replace(
    year=2018,
    month=3,
    day=22,
    hour=23,
    minute=59,
    second=59,
    microsecond=0
)\
.astimezone(pytz.utc)

dt2=datetime(
    year=2018,
    month=3,
    day=22,
    hour=23,
    minute=59,
    second=59,
    microsecond=0,
    tzinfo=pytz.timezone("America/Sao_Paulo")
)\
.astimezone(pytz.utc)

print(dt1)
# 2018-03-23 02:59:59+00:00
print(dt2)
# 2018-03-23 03:05:59+00:00

为什么 dt1 != dt2

我知道 dt1 是创建 datetime 对象的丑陋方法,但这实际上是我期望的值。我不明白为什么他们在 6 分钟内不同。

非常感谢。

引用自 pytz 文档:

Unfortunately using the tzinfo argument of the standard datetime constructors ‘’does not work’’ with pytz for many timezones.

在将 dt2 转换为 UTC 之前先看一下它,您会发现它的 UTC 偏移量有问题:

>>> dt2 = datetime(year=2018, month=3, day=22,
...                hour=23, minute=59, second=59,
...                tzinfo=pytz.timezone("America/Sao_Paulo"))
>>> print(dt2)
2018-03-22 23:59:59-03:06

另一方面,这有效:

>>> naive_dt = datetime(year=2018, month=3, day=22,
...                     hour=23, minute=59, second=59)
>>> aware_dt = pytz.timezone('America/Sao_Paulo').localize(naive_dt)
>>> print(aware_dt)
2018-03-22 23:59:59-03:00