【问题标题】:Python: Check if parsed datetime has correct timezonePython:检查解析的日期时间是否具有正确的时区
【发布时间】:2020-07-03 02:12:43
【问题描述】:

所以,我知道 ISO 格式的日期时间 - 2020-03-15T18:00:00+04:00

我想解析它并验证 tzinfo 是 "Asia/Dubai" (UTC+04:00)。不幸的是,dateutildatetime 没有给我一个足够好的 tzinfo 解析对象的属性,我可以很容易地验证。

>>> from datetime import datetime
>>> from dateutil.parser import isoparse
>>> import pytz
>>> 
>>> dts = "2020-03-15T18:00:00+04:00"
>>> dt = datetime.fromisoformat(dts)
>>> dt.tzinfo
datetime.timezone(datetime.timedelta(seconds=14400))
>>> dt.tzinfo == pytz.timezone("Asia/Dubai")
False
>>> 
>>> dt = isoparse(dts)
>>> dt.tzinfo
tzoffset(None, 14400)
>>> dt.tzinfo == pytz.timezone("Asia/Dubai")
False

我找不到如何处理 tzoffset 对象,以便我可以轻松地将其与时区字符串进行比较。

欢迎任何建议或建议或朝正确方向轻推。

【问题讨论】:

    标签: python datetime pytz python-dateutil


    【解决方案1】:

    我发现了一个我不喜欢的解决方法(比较时区应该更简单,但是是的,这是一个硬域),基于this answer

    >>> tz = pytz.timezone("Asia/Dubai")
    >>> datetime.utcoffset(dt) == tz.utcoffset(dt.replace(tzinfo=None))
    True
    

    【讨论】:

      【解决方案2】:

      问题的答案“解析的日期时间是 'Asia/Dubai'”,特别是当您的“Asia/Dubai”概念意味着 pytz.timezone("Asia/Dubai") 始终为“否”时,因为 dateutil 永远不会附加那个时间区域到您从 ISO 8601 日期时间解析的内容。

      其中一个原因是您正在解析的字符串没有足够的信息来确定生成它的规则集 - 考虑“Asia/Tibilisi”和“Asia/Dubai”都使用UTC+4,但他们确实不代表同一个时区。

      所以问题是:为什么你需要知道这些信息?

      如果您只是想在“亚洲/迪拜”中使用日期时间,最好使用.astimezone 将它们转换为它:

      from dateutil import tz
      from dateutil.parser import isoparse
      
      _DUBAI = tz.gettz("Asia/Dubai")
      def parse_as_dubai(dt_str):
          dt = isoparse(dt_str)
          if dt.tzinfo is None:
              raise ValueError(f"No time zone offset in {dt_str}")
          return dt.astimezone(_DUBAI)
      

      请注意,只要您解析了时区,无论输入字符串最初是否位于“Asia/Dubai”,这始终是准确的。如果没有给出时区,使用astimezone 将使用解析日期时间的系统的系统本地时间,这不是您想要的。

      如果出于某种原因您需要验证原始日期时间与“亚洲/迪拜”具有相同的偏移量(不确定您为什么需要这个,但我想它可能表明日期时间的来源有问题),然后转换为“亚洲/迪拜”并检查偏移量是否是您最好的选择。您可以在上面的代码中添加额外的错误检查:

      from dateutil import tz
      from dateutil.parser import isoparse
      
      _DUBAI = tz.gettz("Asia/Dubai")
      def parse_as_dubai(dt_str):
          dt = isoparse(dt_str)
          if dt.tzinfo is None:
              raise ValueError(f"No time zone offset in {dt_str}")
          rv = dt.astimezone(_DUBAI)
          if dt.utcoffset() != rv.utcoffset():
              raise ValueError(f"{dt_str} not generated in Asia/Dubai!")
          return rv
      

      最后一点,我建议您不要使用pytz,而是使用dateutil.tz,特别是因为您已经在使用dateutil 进行解析。你可以阅读更多关于为什么in this article

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-01-12
        • 2022-01-20
        • 2011-12-27
        • 2020-08-14
        • 1970-01-01
        • 2015-12-23
        • 2011-09-28
        • 2016-06-08
        相关资源
        最近更新 更多