[Datetime-SIG] Adding PEP 495 support to dateutil

Tim Peters tim.peters at gmail.com
Fri Sep 18 17:56:15 CEST 2015

>> After studying both pytz and dateutil offerings, I decided that it is
>> easier to add "fold-awareness" to the later.  I created a fork [1] on
>> Github and added [2] fold-awareness logic to the tzrange class that appears
>> to be the base class for most other tzinfo implementations.  I was
>> surprised how few test cases had to be changed.  It looks like  dateutil
>> test suit does not test questionable (in the absence of fold) behavior.  I
>> will need to beef up the test coverage.

[Paul Ganssle <paul at ganssle.io>]
> Just to clarify on the point of test coverage, I think one of the main
> reasons for this is that, at the moment, dateutil doesn't handle
> ambiguous times well (see Issue #57[1] and Issue #112[2]), so any such
> tests would likely be failing tests.

Because dateutil inherits the default .fromutc(), it's all but certain
it can't handle cases in the IANA database where a zone's base
("standard") offset changed either.

But it's handling gaps & folds due to DST transitions as well as is
_possible_ for a hybrid tzinfo given datetime's original design.
There was no provision in datetime to make it possible for a hybrid
tzinfo to know whether the earlier or later of an ambiguous local time
is intended.  That's not dateutil's fault, and not something any
hybrid tzinfo can solve before PEP 495 is implemented.

dateutil is following the doc's advice to consider an ambiguous time
to be the later (in "standard time"), which in combination with
inheriting the default .fromutc() is enough to ensure that UTC->local
conversion at least mimics the hands on the local clock (skipping
local times at DST start, and repeating some at DST end).  So it's
doing the best it _can_ do now in those respects.

> At the moment, I can't comment on how easy this will be to implement in
> a release version of dateutil if PEP 495 is accepted because I haven't
> looked into it enough, but one thing to be aware of is that
> backwards-compatibility is a high priority here (we'll continue to
> support python 2.6+ for the foreseeable future), so any changes need to
> fall back to sane behavior. Preferably, they would fall back to the
> exact /same/ behavior, regardless of platform and python version.
> Of course, it doesn't seem like your goal right now is to build
> something that can roll out right away as soon as PEP 495 is integrated,
> so there's plenty of time to clean it up and possibly build in a
> compatibility module, I just thought I'd bring that up so you're aware.

The goal of PEP 495 is to make it possible for hybrid tzinfos to
handle all cases of gaps and folds due to any cause whatsoever
(provided that folds are never worse than 2-to-1),  What Alex is
really after here is to kick the tires on PEP 495, to make sure:

1. All cases in the IANA database are in fact solved (that database
   is the richest source of the goofiest zone changes to date).

2. That it's not only possible, but implementable with reasonable effort
   and performance.

dateutil was "the obvious" base to start from, since it's the only
widely used wrapping of the IANA database using hybrid tzinfos (pytz
took a very different path).

Whether dateutil can make _use_ of this experiment is up to you ;-)

In cases where results differ from the current implementation, the
latter results can only be called "wrong".  Which you may well need to

In which case, I'd suggest leaving the current implementation alone,
and _adding_ a new wrapping of tzfiles based on Alex's code.
dateutil's get-a-zone factory functions would need to grow some way to
spell "I want a pre-495 tzinfo" or "I want a post-495 tzinfo".  New
functions, optional function flags, global setting ... whatever you
think works best.

Of course this would apply to wrappings of other sources of zone info
too, but the IANA database must be by far the hardest (e.g., fold and
gap times can be deduced directly from a POSIX TZ string rule, which
are only subject to twice-a-year DST changes at worst).

More information about the Datetime-SIG mailing list