[Python-Dev] Status on PEP-431 Timezones

Lennart Regebro regebro at gmail.com
Sun Jul 26 10:12:15 CEST 2015


On Sun, Jul 26, 2015 at 8:05 AM, Tim Peters <tim.peters at gmail.com> wrote:
> The Python docs also are quite clear about that all arithmetic within
> a single timezone is "naive".  That was intentional.  The _intended_
> way to do "aware" arithmetic was always to convert to UTC, do the
> arithmetic, then convert back.

We can't explicitly implement incorrect timezone aware arithmetic and
then expect people to not use it. We can make the arithmetic correct,
and we can raise an error when doing tz-aware arithmetic in a
non-fixed timezone. But having an implementation we know is incorrect
and telling people "don't do that" doesn't seem like a good solution
here.

Why do we even have timezone aware datetimes if we don't intend them
for usage? There could just be naive datetimes, and timezones, and let
strftime take a timezone that is used when formatting. And we could
make date-time creation into a function that parses data including a
timezone, and returns the UTC time of that data.

But then again, if we do that, we could just as well have that
timezone as an attribute on the datetime object, and let strftime use
so it doesn't have to be passed in. And we could let the __init__ of
the datetime take a timezone and do that initial conversion to UTC.

> Python's datetime never intended to support that directly.

I think it should. It's expected that it supports it, and there is no
real reason not to support it. The timezone handling becomes
complicated if you base yourself on localtime, and simple if you base
yourself on UTC.

As you agree, we recommend to people to use UTC at all times, and only
use timezones for input and output. Well, what I'm now proposing is to
take that recommendation to heart, and change datetime's
implementation so it does exactly that.

I saw the previous mention of "pure" vs "practical", and that is often
a concern. Here it clearly is not. This is a choice between impure,
complicated and impractical, and pure, simple and practical.

> Is it the case that pytz also "fails" in the cases your attempts "fail"?

No, that is not the case. And if you wonder why I just don't do it
like pytz does it, it's because that leads to infinite recursion, much
as discussions on this mailing list does. ;-) And this is because we
need to normalize the datetime after arithmatic, but normalizing is
arithmetics.

> "Batteries included" has some attractions all on its own.  On top of
> that, adding is_dst-like flags to appropriate methods may have major
> attractions.

> Ah, but it already happens that way

No, in fact it does not. Pytz makes that happen only through a
separate explicit normalize() call (and some deep cleverness to keep
track of which timezone offset it is located in). dateutil.tz can't
guarantee these things to be true, because it doesn't keep track of
ambiguous times. So no, it does not already happen that way.

>>> from dateutil.zoneinfo import gettz
>>> from datetime import *
>>> dt = datetime(2015, 11, 1, 0, 30, tzinfo=est)
>>> dt2 = dt + timedelta(hours=1)

>>> utc = gettz('Etc/UTC')
>>> dtutc = dt.astimezone(utc)
>>> dt2utc = dt2.astimezone(utc)
>>> (dt2utc-dtutc).total_seconds()
7200.0

You add one hour, and you get a datetime that happens two hours later.
So no, it does not already happen that way.
In pytz the datetime will be adjusted after you do the normalize call.

> I apologize if I've come off as unduly critical - I truly have been
> _only_ trying to find out what "the problem" is.  That helps!  Thank
> you.  Note that I've had nothing to do with datetime (except to use
> it) for about a decade.  I have no idea what you, or anyone else, has
> said about it for years & years until this very thread caught my
> attention this week.  Heck, for all I know, Guido _demanded_ that
> datetime arithmetic be changed - although I doubt it ;-)

It's not a question of changing datetime arithmetic per se. The PEP
does indeed mean it has to be changed, but only to support ambiguous
and non-existent times.

It's helpful to me to understand, which I hadn't done before, that
this was never intended to work. That helps me argue for changing
datetimes internal implementation, once I get time to do that. (I'm
currently moving, renovating a new house, trying fix up a garden that
has been neglected for years, and insanely, write my own code editor,
all at the same time, so it won't be anytime soon).

> There's more than one decision affecting this  In cases where a single
> local time corresponds to more than one UTC time (typically at the end
> of DST, when a local hour repeats), datetime never did give any clear
> way to do "the intended" conversion from that local time _to_ UTC.
> But resolving such ambiguities has nothing to do with how arithmetic
> works:  it's utterly unsolvable by any means short of supplying new
> info ("which UTC value is intended?" AKA is_dst).

The "changing arithmetic" discussion is a  red herring.

Now my wife insist I help her pack, so this is the end of this
discussion for me. If i continue it will be only as a part of
discussing how we change how datetime works internally.

//Lennart


More information about the Python-Dev mailing list