6

我正在尝试使用 Python 模块比较两次datetime,但我似乎无法time在 UTC 中创建时区感知对象。

>>> import pytz, datetime
>>> UTC_TZ = pytz.utc
>>> EASTERN_TZ = pytz.timezone('America/New_York')
>>> d1 = datetime.time(10, tzinfo = UTC_TZ)
>>> d1
datetime.time(10, 0, tzinfo=<UTC>)
>>> d2 = datetime.time(10, tzinfo = EASTERN_TZ)
>>> d2
datetime.time(10, 0, tzinfo=<DstTzInfo 'America/New_York' EST-1 day, 19:00:00 STD>)
>>> d1 < d2
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can't compare offset-naive and offset-aware times

这是一个错误吗?我需要使用特殊的 UTC 时区吗?这是怎么回事?

4

3 回答 3

9

所有的功劳都归功于 wberry 解决了这个问题,但为了得到一个简洁的答案,我将在这里总结一下。

根据 datetime 文档,在比较两个 datetime.time 对象时:“如果两个比较对象都知道并且具有不同的 tzinfo 属性,则首先通过减去它们的 UTC 偏移量(从 self.utcoffset() 获得)来调整比较对象”

在您给出的示例中,比较会引发 TypeError,因为 EASTERN_TZ.utcoffset() 返回 None。utcoffset 为无,因为美国东部遵守夏令时,因此与 UTC 的时间偏移取决于 datetime.time 中不可用的日期。

您应该使用 datetime.datetime 对象进行跨时区比较:

>>> import pytz, datetime
>>> UTC_TZ = pytz.utc
>>> EASTERN_TZ = pytz.timezone('America/New_York')
>>> d1 = datetime.datetime(2012, 1, 1, 10, 0, tzinfo=UTC_TZ)
>>> d2 = datetime.datetime(2012, 1, 1, 10, 0, tzinfo=EASTERN_TZ)
>>> d1 < d2
True
于 2012-05-09T22:49:32.617 回答
3

您收到错误是因为您试图测量一个time可以绑定到特定 UTC 时刻的time对象与另一个“幼稚”且不能绑定到特定 UTC 时刻的对象之间的差异。解决方法是使两个比较对象都具有偏移感知,或者两者都幼稚。

下面使用datetime对象,但它基本上是相同的想法。

import datetime, time, pytz

EST = pytz.timezone('America/New_York')
UTC = pytz.timezone('Etc/UTC')
dt1 = datetime.datetime.fromtimestamp(time.time(), EST)
# ... time passes
dt2 = datetime.datetime.fromtimestamp(time.time(), UTC)
elapsed = dt2 - dt1
于 2012-05-09T21:47:42.487 回答
1

我猜问题是UTC被认为不是任何时区,或者“偏移天真”,也许?我建议在进行任何比较之前将所有内容都转换为 UTC。

显然,您需要知道输入和输出的时区,但是您应该尝试将内部表示全部保持为 UTC,并且可能只存储每个用户的时区并在需要时进行转换。从长远来看,它会省去很多麻烦。

另外,你不应该这样做。最好用

timezone.localize(dt)

如此处所述:http: //pytz.sourceforge.net/#localized-times-and-date-arithmetic

于 2012-05-09T21:22:57.780 回答