使用 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 进行日期时间和时区转换 - 令人兴奋的行为的主要内容,如果未能解决你的问题,请参考以下文章
python 使用`pytz`将时间和日期对话转换为其他时区。