Home > Enterprise >  Is there a way to infer in Python if a date is the actual day in which the DST (Daylight Saving Time
Is there a way to infer in Python if a date is the actual day in which the DST (Daylight Saving Time

Time:10-08

I would like to infer in Python if a date is the actual day of the year in which the hour is changed due to DST (Daylight Saving Time).

With the library pytz you can localize a datetime and the actual DST change is correctly done. Furthermore, there is the method dst() of the library datetime that allows you to infer if an actual date is in summer or winter time (example). However, I would like to infer the actual day in which a DST change is made.

Concretely, I would need a function (for example is_dst_change(date, timezone)) that receives a date and returns True only for those days of the year that do have an hour change. For example:

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

Thus, in the above example the only days of 2021 for which the function is_dst_change(day, timezone='Europe/Madrid') will return True are 28/03/2021 and 31/10/2021. For the rest of the days of the year 2021, it must return False. Is there a way to infer this with Python?

CodePudding user response:

If today's UTC offset is different than tomorrow's, then today is a DST change.

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))

"Today" is defined in this code as midnight to midnight.

CodePudding user response:

You can make use of datetime.dst() (a change in UTC offset is not necessarily a DST transition):

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()

e.g. for 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

Note: I'm using zoneinfo here instead of pytz; for legacy code, there is a pytz deprecation shim. Here's a pytz version anyway (needs an additional 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()
  • Related