使用 pytz 进行日期时间和时区转换 - 令人兴奋的行为

Posted

技术标签:

【中文标题】使用 pytz 进行日期时间和时区转换 - 令人兴奋的行为【英文标题】:datetime and timezone conversion with pytz - mind blowing behaviour 【发布时间】:2021-09-12 10:46:22 【问题描述】:

我正在尝试将时区感知 datetime 对象转换为 UTC,然后返回到它的原始时区。我有以下sn-p

t = datetime(
    2013, 11, 22, hour=11, minute=0,
    tzinfo=pytz.timezone('Europe/Warsaw')
)

现在在 ipython 中:

In [18]: t
Out[18]: datetime.datetime(
    2013, 11, 22, 11, 0, tzinfo=<DstTzInfo 'Europe/Warsaw' WMT+1:24:00 STD>
)

现在让我们尝试转换为 UTC 并返回。我希望具有与以下相同的表示:

In [19]: t.astimezone(pytz.utc).astimezone(pytz.timezone('Europe/Warsaw'))
Out[19]: datetime.datetime(
    2013, 11, 22, 10, 36, tzinfo=<DstTzInfo 'Europe/Warsaw' CET+1:00:00 STD>
)

但我们看到 Out[18]Out[19] 不同。怎么回事?

【问题讨论】:

Django 存储日期时间朴素数据库明智。如果您处理这种情况,请查看此处将日期转换为您需要的时区:docs.djangoproject.com/en/dev/topics/i18n/timezones/#usage Django 是否存储原始日期时间不是由USE_TZ 设置控制。如果那是True,那么 Django 将表单等中的日期时间视为在current timezone 中,并将它们存储在转换为 UTC 的数据库中。 您能否进一步说明“令人兴奋的行为”?我不喜欢 StackExchange 上的点击诱饵 【参考方案1】:

文档http://pytz.sourceforge.net/ 指出“不幸的是,对于许多时区,使用标准日期时间构造函数的 tzinfo 参数‘不适用于’pytz。”代码:

t = datetime(
    2013, 5, 11, hour=11, minute=0,
    tzinfo=pytz.timezone('Europe/Warsaw')
)

按照这个不行,你应该使用localize方法:

t = pytz.timezone('Europe/Warsaw').localize(
        datetime(2013, 5, 11, hour=11, minute=0))

【讨论】:

Python 日期时间模块假定时区对象具有恒定的 UTC 偏移量。 Pytz 时区对象具有不同的 UTC 偏移量(因为夏令时以及历史时区更改)。当您使用 pytz 的 localize() 时,它可以获取该特定日期的正确偏移量。当您使用 datetime 的 replace(tzinfo==) 时,您最终会得到数据库中该时区最旧的 UTC 偏移量。

以上是关于使用 pytz 进行日期时间和时区转换 - 令人兴奋的行为的主要内容,如果未能解决你的问题,请参考以下文章

使用 pytz 进行日期时间时区转换

python 使用`pytz`将时间和日期对话转换为其他时区。

使用 pytz 将日期时间从一个时区转换为另一个时区

使用pytz的python时区转换问题

Python pytz 时区转换返回的值与不同日期的时区偏移量不同

使用pytz的Datetime时区转换