<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Sun, Aug 16, 2015 at 9:10 PM, Tim Peters <span dir="ltr"><<a href="mailto:tim.peters@gmail.com" target="_blank">tim.peters@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">[Guido]<br>
<span class="">> How did we end up bending over this far backwards for leap seconds?<br>
<br>
</span>Eh - I don't see that we are.  The `first` flag is applicable to any<br>
source of folds and gaps, provided the folds aren't worse than 2-to-1.<br>
Leap seconds are just one more case of that.<br></blockquote><div><br></div><div>That was in reference to PEP 500 more than to the `first` flag.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
If you want to build in gap-and-fold-aware arithmetic, then it seems<br>
only one kind can be supported.  If it's left to tzinfo implementers,<br>
then it's up to them.<span class=""><br></span></blockquote><div><br></div><div>Well, most tzinfo implementers have other priorities; leap-secondists, while loud, are rare enough that the extra freedom just complexificates the API for everyone else without reason.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">
> To me, we're talking about a mapping to POSIX timestamps, which use a<br>
> straightforward algorithm to map compute the date and time -- in particular,<br>
> divmod(ts, 86400) will give the day number and the second within that day.<br>
> The day gets converted to a date using standard calendar math (assuming they<br>
> eventually fix the standard so that 2100 is not considered a leap year :-)<br>
> and the time gets converted to HH:MM:SS using even simpler calculations.<br>
> There's no room for leap seconds there.<br>
<br>
</span>Nobody is proposing to change any of that.  A POSIX timestamp maps to<br>
the same UTC time in any case (including in cases where a POSIX<br>
timestamp is ambiguous, and including cases that produce a UTC time<br>
that never existed (hasn't happened yet, but will when a leap second<br>
gets removed someday)).<br>
<br>
None of that _precludes_ implementing an arithmetic that returns<br>
correct real-life deltas (between real-life UTC times) as SI-second<br>
durations.  That can be done in most (but not all) cases using POSIX<br>
timestamps by consulting a table of leap second adjustments.  It<br>
_could_ be done in all cases (not just most) using first-aware<br>
datetimes, because - unlike bare POSIX timestamps - the `first` flag<br>
gives datetimes a calendar notation that disambiguates the ambiguous<br>
POSIX timestamps.  Do note that POSIX supports a calendar notation for<br>
leap seconds too (allowing tm_sec to be 60).<br></blockquote><div><br></div><div>But datetime does not. IMO a seconds value of 60 is more likely a bug than an attempt to represent a leap second.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
_Given_ a `first`-like flag, nothing beyond that is really required<br>
from Python (although it would be more useful if a way were given to<br>
map a second value of "60" to/from first=False when applicable).<br></blockquote><div><br></div><div>Using the `first` flag sounds like a good compromise then. (Unless leap seconds may happen at a time when some jurisdiction also changes DST?)<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
BTW, POSIX fixed the "2100 is not a leap year" problem in 2001 - but<br>
ancient Internet rants never die ;-)<span class=""><br></span></blockquote><div> </div><div>Good to know. :-)<br> <br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">
> It's important to me that if two different Python implementations, running<br>
> on two different computers, convert a POSIX timestamp to a date+time they<br>
> get the same result.<br>
<br>
</span>That's important to everyone.  It would remain true even if someone<br>
did write an implementation of leap-second-aware arithmetic.<br>
<span class=""><br>
<br>
> This is *much* more important to me than the idea that if two computers<br>
> simultaneously call time.time() they get the same value -- there is simply<br>
> no such thing as "simultaneously" (imagine one of the computers is on<br>
> a rocket traveling to the moon).<br>
<br>
</span>One factoid I learned recently:  the best atomic clocks now are so<br>
bloody sensitive that they run at detectably different rates if their<br>
altitude changes by an inch (due to gravitational time dilation).<br>
<br>
Luckily, nobody yet has demanded Python support relativistic datetime<br>
conversions ;-)<br>
<span class=""><br>
<br>
> If you care about leap seconds you should use a different time source, and<br>
> you shouldn't be using either the time module or the datetime module. They<br>
> are inextricably linked.<br>
<br>
</span>Eh - it's a shallow problem.  Just tedious.  Adding `first` is a<br>
crucial part of the battle for _all_ kinds of gap-and-fold-aware<br>
arithmetic.  And the code for all kinds of the latter is a tedious but<br>
conceptually trivial chore.  Accounting for clocks jumping around is<br>
no harder "theoretically" when the jump is caused by a leap second<br>
than when it's caused by daylight time starting or ending.<br>
<span class=""><br>
<br>
> So there's my answer to #1. You may consider this a Pronouncement if you<br>
> wish. It should not come as any surprise.<br>
<br>
</span>You don't want leap-aware arithmetic in the core.  Neither do I.<br>
<br>
The remaining question is whether you want to make it impossible for<br>
someone else to add it.<span class=""><br></span></blockquote><div><br></div><div>That depends on the cost for everyone else. If the cost is PEP 500, that's too high a price.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">
> And while I'm at it, I don't think PEP 500 is the answer. If you really want<br>
> the number of real-world seconds between two datetime values you can write<br>
> your own difftime() function that consults a leap seconds database.<br>
<br>
</span>That's a start.  Related questions include "the nuclear reactor has to<br>
be vented exactly 3600 SI seconds from now - what will the local clock<br>
say then?".<br></blockquote><div><br></div><div>They should probably use their own clock hardware and software rather than use time.time().<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
I agree such apps "should be" using TAI.  But the one actual scientist<br>
who has posted here most often says they don't get a choice about the<br>
time system used by the data they need to analyze.  I say they should<br>
convert all the data they're given to TAI.  They don't want to hear<br>
that ;-)<span class=""><br></span></blockquote><div><br></div><div>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. <br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">
> As for how to request timeline arithmetic vs. the other kind ("human"? I<br>
> forget where our glossary is), that could be done by special-casing in the<br>
> datetime class using some property (yet to be determined) of the tzinfo<br>
> subclass or instance; or it could be done using different timedelta-ish<br>
> classes. PEP 500 seems overly general just so it can also support the leap<br>
> second case.<br>
<br>
</span>I've mentioned this before:  I think it's insane to try to implement<br>
"human arithmetic" by overloading arithmetic operators.  See the<br>
iCalendar spec for the least people expect now.  Things like "the<br>
first Tuesday after the first Monday in November every 4 years" (US<br>
presidential election dates) are just the start.  Trying to spell all<br>
that with combinations of +-*/% would be a write-only nightmare.<br></blockquote><div><br></div><div>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".<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
dateutil implements the full iCalendar RRULE spec, and sanely uses<br>
functions with lots of keyword arguments.  Nobody is _really_ going to<br>
improve on that.<br>
<br>
So I don't see PEP 500 as aiming at human arithmetic at all (although<br>
others may).  I do see it as a way to:<br>
<br>
1. Keep _all_  gap-and-fold timeline arithmetics out of the core.  I<br>
don''t really want, e.g., DST-aware timeline arithmetic in the core<br>
either.<br>
<br>
2. Let tzinfo implementers decide which kinds of gaps and folds they care about.<br>
<span class=""><br>
<br>
> ("So how do I write a real-time stock trading system", you may ask. Good<br>
> question. Ask the stock exchanges. Their solution was not to trade near the<br>
> leap second. Given that they probably have to deal with a mix of languages<br>
> including at least Java, Cobol, Lisp, Python, and Smalltalk, I'm doubtful<br>
> that they'll do better during the lifetime of Python 3. Famous last words<br>
> perhaps.)<br>
<br>
</span>Most shut down for at least an hour around the last leap second,<br>
because a leap second gets inserted just as the hour (on clocks<br>
running at a multiple-of-hour offset from UTC) is about to change.<br>
Experience taught them last time around that software confusions<br>
quickly propagate across fields :-(<br>
<br>
But that's a different problem.  Python isn't the _source_ of anyone's<br>
notion of time.  CPython inherits all it can know about "what time is<br>
it now?" from the OS and platform C libraries.<br>
</blockquote></div><br></div><div class="gmail_extra">Sure. And?<br clear="all"></div><div class="gmail_extra"><br>-- <br><div class="gmail_signature">--Guido van Rossum (<a href="http://python.org/~guido" target="_blank">python.org/~guido</a>)</div>
</div></div>