[Datetime-SIG] PEP 495 (Local Time Disambiguation) is ready for pronouncement

Tim Peters tim.peters at gmail.com
Tue Aug 18 00:05:24 CEST 2015

>>> How did we end up bending over this far backwards for leap seconds?

>> Eh - I don't see that we are.  The `first` flag is applicable to any
>> source of folds and gaps, provided the folds aren't worse than 2-to-1.
>> Leap seconds are just one more case of that.

> That was in reference to PEP 500 more than to the `first` flag.

Sure, except I read it as being entirely about PEP 500 (since, if leap
seconds had never existed, nothing in PEP 495 would be any different).

I just don't see any "bending over this far backwards" in PEP 500.
It's a simple protocol allowing for implementers of local clocks to
implement arithmetic (and datetime<->string too, if they need it)
reflecting how their local clocks work.  It's not complex.  The
hardest part for _anyone_ will be implementing .utcoffset() and .dst()
to reflect all the goofy local rules.  But even then, that's not
complexity for _users_, it's complexity for a relative handful of
tzinfo authors, and there's no possible way to hide the arbitrary
lumpiness of local rules from the people responsible for
_implementing_ arbitrarily lumpy local rules.

> ...
> Well, most tzinfo implementers have other priorities;

They're not required to implement leap seconds.  Only someone who
_wants_ leap second support has to give a moment's thought to it.

> leap-secondists, while loud, are rare enough that the extra freedom just
> complexificates the API for everyone else without reason.

Can only repeat I don't see undue complexities here.  Did you notice
that PEP 500 already contains a more-or-less complete implementation
of "Olson-aware" timeline arithmetic (i.e., accounting for both DST
transitions and changes to base UTC offset)?  It's straightforward,
not complex (but again assuming .utcoffset() and .dst() have been
implemented to meet PEP 495:  everyone is wishing away ;-) the code
needed to implement "the hard part").

And "everyone else" in this context means just the relative handful of
people in the world motivated enough to wrap the Olson database and/or
POSIX TZ strings and/or Microsoft registry and/or ... timezone sources
in tzinfo subclass objects.  You override the methods you need, and
leave the rest alone.

>> ...
>> Do note that POSIX supports a calendar notation for
>> leap seconds too (allowing tm_sec to be 60).

> But datetime does not. IMO a seconds value of 60 is more likely a bug than
> an attempt to represent a leap second.

That's fine, and appropriate.  For someone who _does_ care about leap
seconds enough to do the work, the PEP 500 protocol allows them to
take over the datetime<->string operations to (if they choose) accept
and/or produce a string with a "second" value of 60 in case of an
inserted leap second.  This doesn't burden anyone else, or make
second=60 an uncaught error in anyone else's tzinfo implementation.
People who do use leap seconds are already acutely aware of what
second=60 means.

>> ...
>> _Given_ a `first`-like flag, nothing beyond that is really required
>> from Python (although it would be more useful if a way were given to
>> map a second value of "60" to/from first=False when applicable).

> Using the `first` flag sounds like a good compromise then.

Internally I expect that's the only way a leap second would be
represented.  The "second=60" part is universally understood already
by people who care about leap seconds, but their expectations about
that begin and end with the strings they type and see.

> (Unless leap seconds may happen at a time when some
> jurisdiction also changes DST?)

If the definition of UTC doesn't change, we'll _eventually_ need to
add at least one leap second every minute ;-)  But for now, they're
only inserted at the end of a June or December, which for physical
reasons are far from any known (by me ;-) ) DST transition points.
I'm more concerned that they'd coincide with a base-offset-from-UTC
transition, since "new year, new timezone!" sounds like something a
politician would like :-(

In any case, even if they do coincide, it's the same as when a DST
transition coincides with a base-UTC-offset change:  it's a potential
headache for the tzinfo implementer, but no problem for anything in
PEPs 495 or 500 _provided that_ folds remain no worse than 2-to-1
(i.e., that a single bit suffices to resolve ambiguities).

> ...
> That depends on the cost for everyone else. If the cost is PEP 500, that's
> too high a price.

What changed?  Not long ago you said you liked the tzstrict idea best.
But seemingly out of nowhere you seem to hate it now.  I don't get it.
To me it still looks simple and straightforward.

> ...
> They should probably use their own clock hardware and software rather than
> use time.time().
> ...
> But what does their data look like? And what time source originally
> generated it (and how does that time source handle leap seconds)? It also
> makes a big difference what kind of intervals they are looking at.

Would answers to those questions make any real difference to you?  If
so, you can dig through all Chris Barker's posts here, or invite him
to write them again ;-)

The answers don't really matter to me, just because it's a fact about
the world that UTC is a compromise between UT1 and TAI.  It was very
deliberate that a UTC second is exactly 1 SI second always, so
scientists relying on local civil time (defined in turn as an offset
from UTC) to record points in time, and computing deltas later, are
just doing something UTC guarantees "will work as expected".  It's not
scientists' fault that computer nerds refuse to support a fundamental
worldwide time standard that happens to be inconvenient for computer
nerds ;-)

[human arithmetic]
> We don't have to spell all of that using arithmetic operators. But we can
> write it all using simple-minded functions on top of operators that behave
> intuitively. E.g. the first Wednesday in November could be determined by
> taking November 1 and then doing something like "while it's not Wednesday,
> add a day".

I strongly encourage everyone interested in "human arithmetic" to look
at what dateutil already does.  It does supply a timedelta-ish
"relative delta" type for doing simple period arithmetic, but goes far
beyond that.


That should be in a different thread, but far as I'm concerned we
should just ask Gustavo to fold it into the core and declare success

>>> ("So how do I write a real-time stock trading system", you may ask...

>> Most shut down for at least an hour around the last leap second ...
>> But that's a different problem ...

> Sure. And?

It was just a polite way of saying "Sure. And?" to you ;-)

More information about the Datetime-SIG mailing list