具有不同时区的两个“时间”对象的比较

Posted

技术标签:

【中文标题】具有不同时区的两个“时间”对象的比较【英文标题】:Comparison of two `time` objects with different timezones 【发布时间】:2014-10-31 15:01:36 【问题描述】:

我正在比较具有不同时区的两个 time 对象,看起来它实际上忽略了时区,只测试小时/分钟/秒组件。

让我们创建两个time 对象:

from datetime import time
import pytz

CET = pytz.timezone('CET')
Japan = pytz.timezone('Japan')

t1 = time(1,2,3, tzinfo=CET)
t2 = time(1,2,3, tzinfo=Japan)

打印它们,我们发现它们非常不同:

datetime.time(1, 2, 3, tzinfo=<DstTzInfo 'CET' CET+1:00:00 STD>)
datetime.time(1, 2, 3, tzinfo=<DstTzInfo 'Japan' JST+9:00:00 STD>)

现在,让我们比较一下:

t1 == t2
#-> True

嗯,什么? Python 怎么可能平等对待它们?

【问题讨论】:

可能相关:Comparing a time in UTC with a time in Eastern time 你用的是什么版本的 Python? @MattDMo,它是 2.7。对不起:) Derp 应该是正确的答案,因为它解释了为什么时间对象是幼稚的 - 它们没有与之关联的日期,并且永远不会知道。 【参考方案1】:

来自关于朴素和有意识的时间对象的文档:

如果 t.tzinfo 不是 None 并且 t.tzinfo.utcoffset(None) 不返回 None,时间对象 t 会知道。

在您的情况下,t1t2 都为 t1.tzinfo.utcoffset(None)t2.tzinfo.utcoffset(None) 返回 None。因此,您的对象是幼稚的,没有意识的。

因此,您有效地将“01:02:03”与“01:02:03”进行比较,即True

【讨论】:

【参考方案2】:

根据https://docs.python.org/2/library/datetime.html#datetime.tzinfo,您的两个时间对象都是“幼稚的”:

如果t.tzinfo 不是None 并且t.tzinfo.utcoffset(None) 不返回None,一个time 对象t 会知道。否则,t 是幼稚的。

print(t1.tzinfo, t1.tzinfo.utcoffset(None))
print(t2.tzinfo, t2.tzinfo.utcoffset(None))

给我们:

(<DstTzInfo 'CET' CET+1:00:00 STD>, None)
(<DstTzInfo 'Japan' JST+9:00:00 STD>, None)

https://docs.python.org/2/library/datetime.html#module-datetime

一个简单的对象不包含足够的信息来明确地定位自己相对于其他日期/时间对象的位置。


换句话说:对象没有日期,因此无法确定是否适用夏令时。它们是模棱两可的,运行t.utcoffset() 将返回None。这使得时区在比较中被完全忽略,因为它们实际上毫无意义。

【讨论】:

即使代码使用了datetime;这是不正确的。应该使用tz.localize() 来制作一个简单的日期时间对象时区感知。【参考方案3】:

我会使用(t1,t1.tzinfo) == (t2, t2.tzinfo)t1.strftime('%H %M %S %Z') == t2.strftime('%H %M %S %Z') 来检查相等性。

derp explained 为什么 Python 将 t1 和 t2 视为相等,并参考此supported operations (Python docs)。

更多参考资料

根据pytz docs,

处理时间的首选方式是始终使用 UTC, 仅在生成要读取的输出时转换为本地时间 人类。

pytz docs 展示了将naive time objects 转换(使用本地化和/或替换)到aware time objects 的方法,还展示了随着时间对象执行算术运算的方法。

【讨论】:

以上是关于具有不同时区的两个“时间”对象的比较的主要内容,如果未能解决你的问题,请参考以下文章

在PostgreSQL中,我们可以直接比较两个不同时区的时间戳吗?

比较某些道具具有不同格式的对象

具有相同时区但不同 utcoffset() 的日期时间对象

在具有正确日期的python中转换和计算日期时间对象的时区

Kellerman Compare .NET Objects:比较具有不同属性名称的不同类型的对象

比较两个对象的不同属性集