【问题标题】:Is this the right way to set a timezone with dateutil?这是使用 dateutil 设置时区的正确方法吗?
【发布时间】:2018-03-25 22:39:09
【问题描述】:
>>> import dateutil.parser, dateutil.tz as tz
>>> dateutil.parser.parse('2017-08-09 10:45 am').replace(tzinfo=tz.gettz('America/New_York'))
datetime.datetime(2017, 8, 9, 10, 45, tzinfo=tzfile('/usr/share/zoneinfo/America/New_York'))

真的是我们应该为解析设置默认时区的方式吗?我已经阅读了 parserexamples 的文档,但我似乎找不到任何内容,“这是如何为 dateutil.parser.parse 设置默认时区”,甚至没有类似的内容。

因为当这个工作时,如果提供了区域,在某些情况下它会做错事。这是否意味着我们应该这样做?

>>> d = dateutil.parser.parse('2017-08-09 10:45 am +06:00')
>>> d = d.replace(tzinfo=d.tzinfo or tz.gettz('America/Chicago'))

因为那也很笨重。

解析时设置默认时区的推荐方法是什么?

【问题讨论】:

  • 您也可以使用default 参数,将其设置为带有时区的日期时间。

标签: python datetime timezone python-dateutil


【解决方案1】:

充实 Paul 的评论 - 因为 datetime 必须至少年、月和日,dateutil 已经有一个它使用的默认值:

>>> from datetime import datetime
>>> datetime.now()
datetime.datetime(2017, 10, 13, 15, 16, 13, 548750)
>>> dateutil.parser.parse('2017')
datetime.datetime(2017, 10, 13, 0, 0)

鉴于此,适当的选择是创建一个包含时区的default,并且要么只是当前日期,要么是任何有意义的日期:

>>> dateutil.parser.parse('2017', default=datetime(2017, 10, 13, tzinfo=tz.gettz('America/New_York')))

当然,你可以将默认值存储为合理的东西,比如default_datetime 或其他东西,那么它就变成了:

>>> dateutil.parser.parse('2017', default=default_datetime)

【讨论】:

    【解决方案2】:

    基本上有两种“正确”的方法可以做到这一点。您可以看到这是在dateutil 的问题跟踪器上以Issue #94 提出的,并且“设置默认时区”被确定为超出范围,因为这可以通过返回的信息轻松完成无论如何都由解析器(因此无需将其构建到解析器本身)。两种方式分别是:

    1. 提供具有时区的default 日期。如果您不关心 default 日期是什么,您可以指定一些日期文字并完成它。如果您希望行为与dateutil 的默认行为基本相同(替换“今天午夜的日期”中的缺失元素),则必须有一些样板:

      from datetime import datetime, time
      from dateutil import tz, parser
      default_date = datetime.combine(datetime.now(),
                                      time(0, tzinfo=tz.gettz("America/New_York")))
      dt = parser.parse(some_dt_str, default=default_date)
      
    2. 使用.replace 的第二种方法:

      from dateutil import parser
      def my_parser(*args, default_tzinfo=tz.gettz("America/New_York"), **kwargs):
          dt = parser.parse(*args, **kwargs)
          return dt.replace(tzinfo=dt.tzinfo or default_tzinfo)
      

    最后一个可能比第一个更干净,但如果在紧密循环中运行,性能会略有下降(因为第一个只需要创建一次默认日期),但 dateutil 的解析器实际上相当慢,所以如果你在一个紧密的循环中运行它,额外的日期构造可能是你的问题最少的。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-02-13
    • 2014-03-16
    • 2012-05-11
    • 2018-12-31
    • 2021-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多