What I need to do
我有一个时区不知道的日期时间对象,我需要添加一个时区,以便能够与其他时区感知日期时间对象进行比较 . 我不想将我的整个应用程序转换为时区而不知道这个遗留案例 .
What I've Tried
首先,要证明问题:
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
>>>
它实际上是在尝试进行转换 . 替换似乎是一个更好的选择(根据Python: How to get a value of datetime.today() 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中都试过这个,结果相同 .
Context
我正在为一些数据文件编写解析器 . 我需要支持旧格式,其中日期字符串没有时区指示符 . 我已经修复了数据源,但我仍然需要支持旧数据格式 . 对于各种商业BS原因,遗留数据的一次转换不是一种选择 . 虽然一般来说,我不喜欢硬编码默认时区的想法,在这种情况下,它似乎是最好的选择 . 我非常有信心地知道所有遗留数据都是UTC格式的,所以我准备接受在这种情况下违约的风险 .
9 回答
我用过dt_aware到dt_unware
和dt_unware到dt_aware
但之前的回答也是一个很好的解决方案 .
所有这些示例都使用外部模块,但您只需使用datetime模块即可获得相同的结果,如this SO answer中所示:
依赖性较少,没有pytz问题 .
注意:如果您希望将它与python3和python2一起使用,您也可以使用它来进行时区导入(硬编码为UTC):
通常,要使天真的日期时间感知,请使用localize method:
对于UTC时区,没有必要使用
localize
,因为没有夏令时计算来处理:作品 . (
.replace
返回一个新的日期时间;它不会修改unaware
. )我同意之前的答案,如果你可以在UTC开始,那就没问题了 . 但我认为这也是人们使用具有 datetime that has a non UTC local timezone. 的tz意识值的常见情况 .
如果您只是按名称去,可能会推断replace()将适用并生成正确的日期时间感知对象 . 不是这种情况 .
the replace( tzinfo=... ) seems to be random in its behaviour . 因此没用 . 不要用这个!
localize是正确使用的功能 . 例:
或者更完整的例子:
给我一个当前本地时间的时区感知日期时间值:
为了增加当地时区; (使用dateutil)
以unutbu的答案形式;我制作了一个实用程序模块来处理这样的事情,语法更直观 . 可以用pip安装 .
我纯粹知道的两种方法
要么
当然,您可以使用任何时区而不是UTC,
我在Django中使用此语句将不知不觉的时间转换为意识到:
这编纂了@Sérgio和@ unutbu的answers . 它将"just work"与
pytz.timezone
对象或IANA Time Zone字符串 .这似乎是
datetime.localize()
(或.inform()
或.awarify()
)应该做的,接受tz参数的字符串和时区对象,如果没有指定时区,则默认为UTC .