【发布时间】:2011-10-27 06:25:44
【问题描述】:
我需要做什么
我有一个不知道时区的 datetime 对象,我需要向它添加一个时区,以便能够将它与其他知道时区的 datetime 对象进行比较。我不想将我的整个应用程序转换为不知道这一遗留案例的时区。
我的尝试
首先,证明问题:
Python 2.6.1 (r261:67515, Jun 24 2010, 21:47:49)
[GCC 4.2.1 (Apple Inc. build 5646)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import datetime
>>> import pytz
>>> unaware = datetime.datetime(2011,8,15,8,15,12,0)
>>> unaware
datetime.datetime(2011, 8, 15, 8, 15, 12)
>>> aware = datetime.datetime(2011,8,15,8,15,12,0,pytz.UTC)
>>> aware
datetime.datetime(2011, 8, 15, 8, 15, 12, tzinfo=<UTC>)
>>> aware == unaware
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can't compare offset-naive and offset-aware datetimes
首先,我尝试了 astimezone:
>>> unaware.astimezone(pytz.UTC)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: astimezone() cannot be applied to a naive datetime
>>>
这并不奇怪,因为它实际上是在尝试进行转换。替换似乎是一个更好的选择(根据How do I get a value of datetime.today() in Python that is "timezone aware"?):
>>> unaware.replace(tzinfo=pytz.UTC)
datetime.datetime(2011, 8, 15, 8, 15, 12, tzinfo=<UTC>)
>>> unaware == aware
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can't compare offset-naive and offset-aware datetimes
>>>
但是正如你所看到的,replace 似乎设置了 tzinfo,但没有让对象知道。我正准备回退到在解析输入字符串之前修改输入字符串以拥有一个时区(如果这很重要,我正在使用 dateutil 进行解析),但这看起来非常笨拙。
另外,我在 Python 2.6 和 Python 2.7 中都尝试过,结果相同。
上下文
我正在为一些数据文件编写解析器。我需要支持一种旧格式,其中日期字符串没有时区指示符。我已经修复了数据源,但我仍然需要支持旧数据格式。由于各种商业 BS 原因,不能选择一次性转换遗留数据。虽然总的来说,我不喜欢硬编码默认时区的想法,但在这种情况下,它似乎是最好的选择。我有理由相信所有有问题的旧数据都使用 UTC,因此我准备接受在这种情况下默认使用 UTC 的风险。
【问题讨论】:
-
unaware.replace()将返回None如果它正在就地修改unaware对象。 REPL 显示.replace()在此处返回一个新的datetime对象。 -
我来这里时需要什么:
import datetime; datetime.datetime.now(datetime.timezone.utc) -
@MartinThoma 我会使用命名的
tzarg 以提高可读性:datetime.datetime.now(tz=datetime.timezone.utc) -
astimezone()现在可以(从 3.6 开始)在一个 naive 对象上调用,并且可以省略它的参数(从 3.3 开始),所以解决方法就像unaware.astimezone()一样简单
标签: python datetime timezone python-datetime pytz