繁体   English   中英

有没有办法在 Python 中推断日期是否是 DST(夏令时)更改发生的实际日期?

[英]Is there a way to infer in Python if a date is the actual day in which the DST (Daylight Saving Time) change is made?

我想在 Python 中推断日期是否是一年中由于 DST(夏令时)而改变小时的实际日期。

使用pytz库,您可以本地化日期时间并正确完成实际的 DST 更改。 此外,库datetime的方法dst()允许您推断实际日期是夏令时还是冬令时( example )。 但是,我想推断出进行 DST 更改的实际日期。

具体来说,我需要一个 function(例如is_dst_change(date, timezone) )接收日期并仅在一年中确实有小时变化的那些日子返回 True 。 例如:

import pytz
import datetime

def is_dst_change(day, timezone):
    # Localize
    loc_day = pytz.timezone(timezone).localize(day)

    # Pseudocode: Infer if a date is the actual day in which the dst hour change is made
    if loc_day is dst_change_day:
        return True
    else:
        return False

# In the timezone 'Europe/Madrid', the days in which the DST change is made in 2021 are 28/03/2021 and 31/10/2021
is_dst_change(day=datetime.datetime(year=2021, month=3, day=28), timezone = 'Europe/Madrid')  # This should return True
is_dst_change(day=datetime.datetime(year=2021, month=10, day=31), timezone = 'Europe/Madrid')  # This should return True
is_dst_change(day=datetime.datetime(year=2021, month=2, day=1), timezone = 'Europe/Madrid')  # This should return False
is_dst_change(day=datetime.datetime(year=2021, month=7, day=1), timezone = 'Europe/Madrid')  # This should return False

因此,在上面的示例中,function is_dst_change(day, timezone='Europe/Madrid')将返回True的 2021 年只有 28/03/2021 和 31/10/2021。 对于 2021 年的第 rest 天,它必须返回False 有没有办法用 Python 来推断这个?

如果今天的 UTC 偏移量与明天的不同,那么今天是 DST 变化。

def is_dst_change(day: datetime.datetime, timezone):
    # Override time to midnight
    day = day.replace(hour=0, minute=0, second=0, microsecond=0)
    tz = pytz.timezone(timezone)
    return(tz.utcoffset(day+datetime.timedelta(days=1)) != 
            tz.utcoffset(day))

“今天”在此代码中定义为午夜至午夜。

您可以使用datetime.dst() (UTC 偏移量的变化不一定是 DST 转换):

from datetime import datetime, time, timedelta
from zoneinfo import ZoneInfo # Python 3.9+

def is_date_of_DSTtransition(dt: datetime, zone: str) -> bool:
    """
    check if the date part of a datetime object falls on the date
    of a DST transition.
    """
    _d = datetime.combine(dt.date(), time.min).replace(tzinfo=ZoneInfo(zone))
    return _d.dst() != (_d+timedelta(1)).dst()

例如 tz Europe/Berlin

for d in range(366):
    if is_date_of_DSTtransition(datetime(2021, 1, 1) + timedelta(d), "Europe/Berlin"):
        print((datetime(2021, 1, 1) + timedelta(d)).date())
# 2021-03-28
# 2021-10-31

注意:我在这里使用zoneinfo而不是pytz 对于遗留代码,有一个pytz deprecation shim 无论如何,这是一个pytz版本(需要额外的normalize ):

import pytz
def is_date_of_DSTtransition(dt: datetime, zone: str) -> bool:
    _d = pytz.timezone(zone).localize(datetime.combine(dt.date(), time.min))
    return _d.dst() != pytz.timezone(zone).normalize(_d+timedelta(1)).dst()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM