[Datetime-SIG] IANA TZ database statistics

Tim Peters tim.peters at gmail.com
Thu Sep 24 19:06:48 CEST 2015

>> ...
>> Specifically which features?  Do you just mean .astimezone() treating
>> a naive datetime as being in the system zone, and the absence of any
>> argument implying the system zone?  Or more than just that?

> Also, .timestamp() respecting the fold attribute and datetime.now() and
> datetime.fromtimestamp() setting the fold attribute appropriately.  In all
> these cases one needs to know how far the transition point is from a given
> time.

Got it.  I should have known that the first time - sorry ;-)

>> In that case, "best" is returning what the IANA database
>> says should be returned in all cases.

> The database itself does not say anything about what should be returned by
> various tools, but I would interpret that as "whatever zdump returns."

Gimme a break.

> ...
> I don't think Windows comes with any, but I know close to nothing about
> Windows.

Windows has minimal (compared to IANA) time zone info stored in the
registry.  You can look at dateutil's tzwin.py for code accessing it.
Zones generally store no historical info, and assume a zone switches
DST zero or two times per year..  In the latter case, the registry
essentially stores a compiled version of the "n'th weekday of the
month" flavor of POSIX TZ string rules, so code can compute when DST
starts and ends each year.  tzwin.py's tzwinlocal class implements a
hybrid tzinfo appropriate for the current system zone (although it
never worked for me :-( ).

So, ironically enough, this could all be relatively straightforward on
Windows:  in return for sticking to regular rules, you get to know the
rules up front.

For portable code, think of Windows as implementing as little as POSIX
requires of localtime() and mktime().  While it uses a 64-bit type for
time_t, values must be >= 0 and are documented as working only through
31 December 3000 23:59:59 UTC.  On my Windows 10 box, it actually goes
21 whole hours ;-) beyond that:"

Python 3.4.3 (v3.4.3:9b73f1c3e601, Feb 24 2015, 22:44:40) [MSC v.1600
64 bit (AMD64)] on win32
>>> datetime.utcfromtimestamp(32535215999)
datetime.datetime(3000, 12, 31, 23, 59, 59)

>>> datetime.utcfromtimestamp(32535215999 + 21 * 3600)
datetime.datetime(3001, 1, 1, 20, 59, 59)

>>> datetime.utcfromtimestamp(32535215999 + 21 * 3600 + 1)
Traceback (most recent call last):
  File "<pyshell#36>", line 1, in <module>
    datetime.utcfromtimestamp(32535215999 + 21 * 3600 + 1)
OSError: [Errno 22] Invalid argument

>> I also agree figuring out the system zone's rules is a puzzle using
>> POSIX.  Note that Gustavo gave up on trying to use mktime() in
>> dateutil's tzlocal class.

> I think he was bitten by the flaky behavior of mktime() when tm_isdst
> is passed as -1.

Good point!

> I intend calling mktime twice with tm_isdst=0 and tm_isdst=1 and detect
> fold/gap by what mktime that does to the tm structure.  If we discover
> that some systems misbehave even in tm_isdst>=0 cases, we can roll
> out our own mktime() that probes localtime() multiple times.

Just one suggestion:  force the year/timestamp into a 400-year span
starting at 1971 first (via adding/subtracting multiples of 400
years).  Then not even Windows will blow up ;-)

> ...

More information about the Datetime-SIG mailing list