'Check if Date is in Daylight Savings Time for Timezone Without pytz

For certain reasons, my employer does not want to use pip to install third party packages and wants me to use packages only hosted on trusty. Thus, I now cannot use pytz in my code. How would I go about checking if a certain date in a timezone is in DST? Here's my original code using 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


Solution 1:[1]

In the general case this is a complex problem that is not amenable to a hand-rolled solution. Relying on an external module that is vetted and maintained by someone dedicated to the task, such as pytz, is the only sane option.

However given the constraint that you're only interested in U.S. time zones, Eastern in particular, it's possible to write a simple function. It is obviously only good for the current (2016) rules, which last changed in 2007 and might change again at any time. Those rules state that DST starts on the second Sunday in March and ends on the first Sunday in November.

This code is based on 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

Solution 2:[2]

Install pytz without using pip.

DST is arbitrary and chosen by legislation in different regions, you can't really calculate it - look at the pytz source for US/Eastern, for example, it's literally a list of hard-coded dates when DST changes for the next twenty years.

You could do that yourself, pulling the data from the same source that pytz does ( ZoneInfo / [or this link] (http://www.iana.org/time-zones) ). or from your OS implementation of tz if it has one...

but (unless it's a licensing reason) get your employer to look at the pytz source and confirm that it's acceptably harmless and approve it for use.

Solution 3:[3]

There is a new capability starting with Python 3.9: the built-in zoneinfo module. If your OS has time zone information built in, this module will access it without needing any additional installed packages.

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

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Community
Solution 2 TessellatingHeckler
Solution 3 Mark Ransom