[Datetime-SIG] Are there any "correct" implementations of tzinfo?

Alexander Belopolsky alexander.belopolsky at gmail.com
Sun Sep 13 02:46:45 CEST 2015

On Sat, Sep 12, 2015 at 6:24 PM, Guido van Rossum <guido at python.org> wrote:

> The repeated claims (by Alexander?) that astimezone() has the power of
> pytz's localize() need to stop.

Prove me wrong! :-)

> Those pytz methods work for any (pytz) timezone -- astimezone() with a
> default argument only works for the local time zone.

That's what os.environ['TZ'] = zonename is for.  The  astimezone() method
works for every timezone installed on your system.  Try it - you won't even
need to call time.tzset()!

> (And indeed what it does is surprising, except perhaps to pytz users.)

That I agree with.  Which makes it even more surprising that I often find
myself and pytz advocates on the opposite sides of the fence.

Granted, setting TZ is a silly trick, but one simple way to bring a full TZ
database to Python is to allow .astimezone() take a zonename string like
'Europe/Amsterdam' or 'America/Montevideo' as an argument and act as
os.environ['TZ'] = zonename; t.astimezone() does now, but without messing
with global state.

I made this suggestion before, but I find it inferior to "as intended"

The only real claim that I am making is that fictitious fixed offset
timezones are useful and we already have some support for them in stdlib.
The datetime.timezone instances that .astimezone() attaches as tzinfo are
not that different from the instances that are attached by pytz's localize
and normalize methods.

In fact, the only major differences between datetime.timezone instances and
those used by pytz is that pytz's EST and EDT instances know that they come
from America/New_York, while datetime.timezone instances don't.  That's why
once you specify America/New_York in localize, your tzinfo.normalize knows
it implicitely, while in the extended .astimezone() solution you will have
to specify it again.  This is not a problem when you only support one local
timezone, but comes with a different set of tradeoffs when you have
multiple timezones.

One advantage of not carrying the memory of the parent zoneinfo in the
fixed offset tzinfo instance is that pickling of datetime objects and their
interchange between different systems becomes simpler.  A pickle of a
datetime.timezone instance is trivial - same as that of a tuple of
timedelta and a short string, but if your fixed offset tzinfo carries a
reference to a potentially large zoneinfo structure, you get all kinds of
interesting problems when you share them between systems that have
different TZ databases.

In any case, there are three approaches to designing a TZ database
interface in the datetime module: the "as intended" approach, the pytz
approach and the astimezone(zonename:str) approach.  The last two don't
require a fold attribute to disambiguate end-of-dst times and the first one
does.  With respect to arithmetic, the last two approaches are equivalent:
both timeline and classic arithmetics are possible, but neither is
painless.  The "as intended" approach comes with classic arithmetic that
"just works" and encourages the best practice for timeline arithmetic: do
it in UTC.  That's why I believe PEP 495 followed by the implementation of
fold-aware "as intended" tzinfos (either within stdlib or by third parties)
is the right approach.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/datetime-sig/attachments/20150912/c0dc493c/attachment-0001.html>

More information about the Datetime-SIG mailing list