[Python-Dev] Status on PEP-431 Timezones

Tim Peters tim.peters at gmail.com
Mon Jul 27 04:04:51 CEST 2015

[Paul Moore <p.f.moore at gmail.com>]
> I think the current naive semantics are useful and should not be
> discarded lightly. At an absolute minimum, there should be a clear,
> documented way to get the current semantics under any changed
> implementation.

Realistically, default arithmetic behavior can't change in Python 3
(let alone Python 2).  Pushing for a different design is fine, but
that can't be sold on the grounds that current behavior is "a bug" -
it's working as designed, as intended, and as documented, and hasn't
materially changed in the dozen-or-so years since it was introduced.
It's not even that the proposed alternative arithmetic is "better",
either:  while it's certainly more suitable for some applications,
it's certainly worse for others.  Making an incompatible change would
be (& should be) a hard sell even if there were a much stronger case
for it than there is here.

But that's just arithmetic.  Some way to disambiguate local times, and
support for most zoneinfo time zones, are different issues.

> As an example, consider an alarm clock. I want it to go off at 7am
> each morning. I'd feel completely justified in writing tomorrows_alarm
> = todays_alarm + timedelta(days=1).
> If the time changes to DST overnight, I still want the alarm to go off
> at 7am. Even though +1 day is in this case actually + 25 (or is it
> 23?) hours. That's the current semantics.

There was a long list of use cases coming to the same conclusion.  The
current arithmetic allows uniform patterns in local time to be coded
in uniform, straightforward ways.  Indeed, in "the obvious" ways.  The
alternative behavior favors uniform patterns in UTC, but who cares?
;-)  Few local clocks show UTC.  Trying to code uniform local-time
behaviors using "aware arithmetic" (which is uniform in UTC. but may
be "lumpy" in local time) can be a nightmare.

The canonical counterexample is a nuclear reactor that needs to be
vented every 24 hours.  To which the canonical rejoinder is that the
programmer in charge of that system is criminally incompetent if
they're using _any_ notion of time other than UTC ;-)

> To be honest, I would imagine, from experience with programmers
> writing naive algorithms, that the current semantics is a lot less
> prone to error when used by such people. People forget about timezones
> until they are bitten by them, and if they are using the convert to
> UTC->calculate->convert back model, their code ends up with
> off-by-1-hour bugs. Certainly such mistakes can be fixed, and the
> people who make them educated, but I like the fact that Python's
> typical behaviour is to do what a non-expert would expect. By all
> means have the more sophisticated approach available, but if it's the
> default then naive users have to either (1) learn the subtleties of
> timezones, or (2) learn how to code naive datetime behaviour in Python
> before they can write their code. If the current behaviour remains the
> default, then *when* the naive user learns about the subtleties of
> timezones, they can switch to the TZ-aware datetime - but that's a
> single learning step, and it can be taken when the user is ready.

There is a design flaw here, IMO:  when they switch to a TZ-aware
datetime, they _still_ get "naive" arithmetic within that time zone.
It's at best peculiar that such a datetime is _called_ "aware" yet
still ignores the time zone rules when doing arithmetic.  I would have
preferred a sharper distinction, like "completely naive" (tzinfo
absent) versus "completely aware" (tzinfo present).  But, again, it's
working as designed, intended and documented.

One possibility to get "the other" behavior in a backward-compatible
way:  recognize a new magic attribute on a tzinfo instance, say,
__aware_arithmetic__.  If it's present, arithmetic on a datetime with
such a tzinfo member "acts as if" arithmetic were done by converting
to UTC first, doing the arithmetic, then converting back.  Otherwise
(magic new attribute not present) arithmetic remains naive.  Bonus:
then you could stare at datetime code and have no idea which kind of
arithmetic is being used ;-)

> PS I don't think the above is particularly original - IIRC, it's
> basically Guido's argument for naive datetimes from when they were
> introduced. I think his example was checking his watch while on a
> transatlantic plane flight, but the principle is the same.

Yup, your account is fair (according to me ;-) ).  Here's Guido's
first message on the topic:


More information about the Python-Dev mailing list