具有不同时区的两个“时间”对象的比较
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 会知道。
在您的情况下,t1
和 t2
都为 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中,我们可以直接比较两个不同时区的时间戳吗?