【问题标题】:Check if Date is in Daylight Savings Time for Timezone Without pytz检查日期是否在没有 pytz 的时区的夏令时
【发布时间】:2016-08-02 14:08:41
【问题描述】:

出于某些原因,我的雇主不想使用 pip 来安装第三方软件包,而是希望我使用仅托管在 trusty 上的软件包。因此,我现在不能在我的代码中使用 pytz。我将如何检查时区中的某个日期是否在 DST 中?这是我使用 pytz 的原始代码。

    import pytz
    import datetime
    ...

    target_date = datetime.datetime.strptime(arg_date, "%Y-%m-%d")
    time_zone = pytz.timezone('US/Eastern')
    dst_date = time_zone.localize(target_date, is_dst=None)
    est_hour = 24
    if bool(dst_date.dst()) is True:
        est_hour -= 4
    else:
        est_hour -= 5

【问题讨论】:

  • 您是只担心美国时区还是需要在全球范围内运营?
  • 我唯一关心的时区是美国东部。

标签: python python-3.x datetime


【解决方案1】:

在一般情况下,这是一个复杂的问题,不适合手动解决。依靠由专门负责该任务的人员审查和维护的外部模块,例如pytz,是唯一明智的选择。

但是,鉴于您只对美国时区感兴趣,尤其是东部时区,您可以编写一个简单的函数。这显然只适用于当前 (2016) 规则,last changed in 2007 并且可能随时再次更改。这些规则规定 DST starts on the second Sunday in March and ends on the first Sunday in November

此代码基于my algorithm for finding a particular day of a month

def is_dst(dt):
    if dt.year < 2007:
        raise ValueError()
    dst_start = datetime.datetime(dt.year, 3, 8, 2, 0)
    dst_start += datetime.timedelta(6 - dst_start.weekday())
    dst_end = datetime.datetime(dt.year, 11, 1, 2, 0)
    dst_end += datetime.timedelta(6 - dst_end.weekday())
    return dst_start <= dt < dst_end

【讨论】:

  • 我想这是尽可能接近不使用 pytz。感谢您的帮助。
【解决方案2】:

在不使用 pip 的情况下安装 pytz

DST 是任意的,由不同地区的立法选择,你无法真正计算它 - 看看 the pytz source for US/Eastern, for example,它实际上是 DST 未来二十年变化的硬编码日期列表。

您可以自己做,从与 pytz 相同的来源(ZoneInfo / [或此链接] (http://www.iana.org/time-zones) )中提取数据。或者从您的 tz 操作系统实现(如果有的话)...

但是(除非它是许可原因)让您的雇主查看 pytz 源并确认它是可以接受的无害并批准使用它。

【讨论】:

  • 感谢您的建议。他们一般不想使用 pip 或任何包管理器的原因是,根据他们的说法,TechOps 团队太小而无法管理每种语言的包管理器,并且由于每种语言的安全更新而不得不处理更新包“对他们来说是一种痛苦”。我怀疑他们会批准在没有 pip 的情况下安装 pytz。希望他们是合理的并批准使用它。
【解决方案3】:

从 Python 3.9 开始有一个新功能:内置 zoneinfo module。如果您的操作系统内置了时区信息,则此模块无需任何额外安装的软件包即可访问它。

>>> import zoneinfo
>>> time_zone = zoneinfo.ZoneInfo('US/Eastern')
>>> dst_date = datetime.datetime(2022, 1, 1, tzinfo=time_zone)
>>> dst_date
datetime.datetime(2022, 1, 1, 0, 0, tzinfo=zoneinfo.ZoneInfo(key='US/Eastern'))
>>> dst_date.dst()
datetime.timedelta(0)
>>> dst_date2 = datetime.datetime(2022, 3, 15, tzinfo=time_zone)
>>> dst_date2
datetime.datetime(2022, 3, 15, 0, 0, tzinfo=zoneinfo.ZoneInfo(key='US/Eastern'))
>>> dst_date2.dst()
datetime.timedelta(seconds=3600)

【讨论】:

    猜你喜欢
    • 2018-01-12
    • 2022-01-20
    • 2015-02-26
    • 2012-06-06
    • 2012-05-26
    • 2020-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多