[Datetime-SIG] PEP-431/495

Tim Peters tim.peters at gmail.com
Fri Aug 28 05:18:20 CEST 2015

[Akira Li <4kir4.1i at gmail.com>]
> I agree on the best practices here. I would prefer that __add__ would be
> forbidden for local timezones unless they have a fixed utc offset. But
> it might be too late for that now.

It's many years too late to change anything about datetime arithmetic
in any backward-incompatible way.

> If __add__ is allowed for timezone-aware datetime objects

It already is.

> then arithmetic "as though via conversion to utc time" is *equally valid* as
> the arithmetic "as though it is a timezone-naive datetime object".aa

 __add__ can only mean one of them.  And it already does.  It _could_
have meant the other, but it doesn't.


>> Apps that care about leap seconds _should_ be using TAI.  Apps that
>> want timeline arithmetic _should_ be using UTC.  Unfortunately, people
>> shoot themselves in the feet all the time.  Python can't stop that.
>> But it doesn't have to _cater_ to poor practices either.

> By your logic: Apps that care about timezone-naive arithmetic _should_
> be using naive datetime objects.

As I've said several times before, that's indeed what I would have
_preferred_.  But it was only a mild preference.  Since timeline
arithmetic is far better done in UTC anyway, I'm "happy enough" with
aware datetimes using classic arithmetic.  Indeed, my own code uses
that frequently, and so does datetime's implementation.  Several
examples of that have been given in other messages.

> I agree it is a poor practice to perform arithmetic on localized time.
> But as long as such arithmetic *is* allowed then it *is* ambiguous what
> type of arithmetic should be used.  There is no *one obvious* way here.

Sure.  But this isn't a case of "in the face of ambiguity refuse the
temptation to guess".  It's a case of "in the face of ambiguity, pick
one, document the choice, and move on".  Similarly, when printing a
floating point number, there are _many_ equally valid choices for how
many digits to display after the decimal point.  That's no argument
for refusing to print floats.  Python has made different choices about
that over time.  If you don't like Python's default choice, with
enough extra work you can force any number of digits you like.  And if
you don't like classic arithmetic, with enough extra work you can get
any other kind of datetime arithmetic you like.

>>> ...
>>> dateutil doesn't work during DST transitions but PEP 495 might allow to
>>> fix it.
> I've linked to a couple of dateutil bugs previously in PEP-431/495
> thread [1]
> I was surprised as you that dateutil .fromutc() appears to be broken.
> I use "might" because I haven't read dateutil code. I can't be sure
> e.g., what backward-compatibility concerns might prevent PEP 495 fix its
> issues with an ambigous local time.

Sorry, I haven't been (and won't be) making time to stare at bugs in
other packages.  I probably know less about them than you do anyway.
Python has always had tests for proper DST transition UTC->local
conversions for the kind of tzinfo classes the docs suggest writing.
But do note that "proper" in this context _only_ means "mimics the
local clock" (gets the repeated or missing YYYY-MM-DD HH:MM:SS
behaviors right).  Without a disambiguation flag, it's flatly
impossible to always get the zone name and/or UTC offset right for
ambiguous local-clock hours.

> Timezones is a very complicated
> topic -- no solution works in the general case.a

?  Timezone transitions are mathematically trivial.  They're just full
of lumps (irregularities).

> ...
> The only my objection that timezone-naive arithmetic is somehow superior
> for localized times.

It's not only superior, it's essential for some purposes.  For other
purposes, it''s worse than useless.

> Though I don't mind it as long as timezone conversions would work.

Good!  That's precisely what PEP 495 intends to make possible.

> ...
>>> If dateutil can be fixed to work correctly using the disambiguation flag
>>> then its behavior is preferable because it eliminates localize,
>>> normalize calls

> ...
> The key word here is "If". *If* it works; great.

I can't speak for dateutil or its author.  But we're not doing brain
surgery here.  Conversion just isn't a deep problem.  The only
non-trivial cases involve ambiguous times.  C fixed that long before
Python existed with is_dst, although granted that mktime() is
notoriously flaky across platforms in edge cases.

> It is still possible to perform both types of arithmetic as the examples
> above demonstrate.

That's always been possible - except for errors in timeline arithmetic
inherited from the rare failing conversion cases.  495 allows to
repair all failures.

> ... [more about pytz and dateutil] .;..

Please don't take offense at my chopping this.  It's only that I need
to make _some_ time tonight for 495 ;-)

More information about the Datetime-SIG mailing list