如何在python中感知不知道的日期时间时区

我需要做什么

我有一个时区不知道的日期时间对象,我需要添加一个时区,以便能够将其与其他可识别时区的日期时间对象进行比较。 我不想将我的整个应用程序转换为不知道这个传统案例的时区。

我试过的

首先,展示问题:

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:如何获得datetime.today()的值是“时区感知”?):

>>> 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
>>> 

但正如你所看到的,替换似乎设置tzinfo,但不能让对象知道。 我准备好回头去修复输入字符串,然后解析它(我使用dateutil进行解析,如果这很重要),但看起来非常糟糕。

另外,我已经在python 2.6和python 2.7中尝试了这一点,并得到了相同的结果。

上下文

我正在为某些数据文件编写解析器。 有一种旧格式,我需要支持日期字符串没有时区指示符的地方。 我已经修复了数据源,但我仍然需要支持传统的数据格式。 遗留数据的一次转换不是用于各种业务BS理由的选项。 虽然一般来说,我不喜欢硬编码默认时区的想法,在这种情况下,它似乎是最好的选择。 我有充分的信心知道,所有有问题的遗留数据都是UTC,所以我准备接受在这种情况下违约的风险。


通常,要使天真的日期时间可识别,请使用localize方法:

import datetime
import pytz

unaware = datetime.datetime(2011, 8, 15, 8, 15, 12, 0)
aware = datetime.datetime(2011, 8, 15, 8, 15, 12, 0, pytz.UTC)

now_aware = pytz.utc.localize(unaware)
assert aware == now_aware

对于UTC时区,由于没有夏时制计算来处理,所以不需要使用localize

now_aware = unaware.replace(tzinfo=pytz.UTC)

作品。 ( .replace返回一个新的日期时间;它不会不unaware修改。)


我曾经从dt_aware到dt_unware

dt_unaware = dt_aware.replace(tzinfo=None)

和dt_unware到dt_aware

from pytz import timezone
localtz = timezone('Europe/Lisbon')
dt_aware = localtz.localize(dt_unware)

但之前的回答也是一个很好的解决方案。


所有这些示例都使用外部模块,但只需使用日期时间模块即可获得相同的结果。

from datetime import datetime
from datetime import timezone

dt = datetime.now()
dt.replace(tzinfo=timezone.utc)

print(dt.replace(tzinfo=timezone.utc).isoformat())
'2017-01-12T22:11:31+00:00'

更少的依赖性和没有pytz问题。

注意:如果你想在python3和python2中使用它,你也可以在导入时区时使用它(硬编码为UTC):

try:
    from datetime import timezone
    utc = timezone.utc
except ImportError:
    #Hi there python2 user
    class UTC(tzinfo):
        def utcoffset(self, dt):
            return timedelta(0)
        def tzname(self, dt):
            return "UTC"
        def dst(self, dt):
            return timedelta(0)
utc = UTC()
链接地址: http://www.djcxy.com/p/18757.html

上一篇: How to make an unaware datetime timezone aware in python

下一篇: Convert UTC/GMT time to local time