【问题标题】: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 怎么可能平等对待它们?

【问题讨论】:

  • 你用的是什么版本的 Python?
  • @MattDMo,它是 2.7。对不起:)
  • Derp 应该是正确的答案,因为它解释了为什么时间对象是幼稚的 - 它们没有与之关联的日期,并且永远不会知道。

标签: python python-2.7 datetime time pytz


【解决方案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 的方法,还展示了随着时间对象执行算术运算的方法。

    【讨论】:

      猜你喜欢
      • 2016-01-07
      • 1970-01-01
      • 1970-01-01
      • 2019-12-06
      • 2017-08-04
      • 1970-01-01
      • 2017-08-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多