Home > Software design >  How does ZoneInfo handle DST in the distant future?
How does ZoneInfo handle DST in the distant future?

Time:11-23

I'm trying to understand how the zoneinfo module figures out daylight savings time transitions in the distant future while it seems that dateutil and pytz both give up on daylight savings time transitions.

I know these transitions aren't really meaningful that far in the future but the inconsistency is potentially a problem and source of confusion.

import datetime
import zoneinfo
import pytz
from dateutil.tz import gettz as dateutil_gettz

eastern_zone = zoneinfo.ZoneInfo('America/New_York')
eastern_pytz = pytz.timezone('America/New_York')
eastern_dateutil = dateutil_gettz('America/New_York')

dates_7000 = [datetime.datetime(7000, month, 1) for month in range(1, 13)]
dates_7000_zone = [d.replace(tzinfo=eastern_zone) for d in dates_7000]
dates_7000_pytz = [eastern_pytz.localize(d) for d in dates_7000]
dates_7000_dateutil = [d.replace(tzinfo=eastern_dateutil) for d in dates_7000]

# for zoneinfo, there are two utcoffsets in this set
# datetime.timedelta(days=-1, seconds=68400)
# datetime.timedelta(days=-1, seconds=72000)
{d.utcoffset() for d in dates_7000_zone}

# for pytz and dateutil there is only one
# datetime.timedelta(days=-1, seconds=68400)
{d.utcoffset() for d in dates_7000_pytz}
{d.utcoffset() for d in dates_7000_dateutil}

I believe that zoneinfo is just carrying the final rule forward indefinitely. Is there anyway to figure out what that rule is and create a pytz or dateutil timezone that would follow it?

CodePudding user response:

Unlike dateutil.tz and pytz, the zoneinfo module is capable of parsing Version 3 TZif files, and Version 3 MAY (read: usually do) contain a footer describing a recurring rule for DST transitions. The part of the Python implementation of zoneinfo relating to these rule-based transitions can be found here. This capability is important for a number of reasons:

  1. Version 1 TZif files store transition times as 32 bit offsets from the Unix Epoch, and as such are subject to the Epochalypse. Right now, 2038 is in the far future, but in 16 years it will be the present, and it will not be possible to express new transitions using Version 1 files.

  2. The tz project offers both "fat" and "slim" binaries — fat binaries include hard-coded transitions for some decently large number of years, even for zones that have simple rule-based offsets, but "slim" binaries store the minimum number of transition times necessary to accurately describe the zone. This means that for zones with rule-based transitions, the Version 1 files truncate in the past, and dateutil.tz and pytz won't even work for current datetimes. Some distros have tried transitioning from fat to slim binaries but have been bitten by patchy support for Version 3 files. Presumably when some threshold is reached, they will all transition to slim files, since there's no particular reason not to and it involves shipping less data.

Of course, my normal disclaimer here applies (one that you have clearly internalized, but it bears repeating): The time zone data available is decently accurate for the period from 1970 to today, and the further away from that time period you go in either direction (the past or the future), the less meaningful the data gets. For dates in even the near future, zoneinfo is showing you the best guess that the tz project maintainers have for what time it's going to be in a different zone, and those guesses become less accurate the further into the future you go.

  • Related