On 07/30/2015 10:46 AM, Chris Barker wrote:
There is "correct" and incorrect, but I"m not arguing that anything is incorrect about the current behavior -- I thought a timedelta was a duration, but I was wrong, it is a Period in units of days (I think!), and sure it apparently does that right.
No, it isn't a Period, and it doesn't "do that right". The current behavior _is_ incorrect (or at least lacking in internal coherence), and I don't think we can get clarity on what we want unless we acknowledge that.
The discussion keeps getting sidetracked on the red herring of whether there are use cases for period arithmetic with "one day" defined as "same local time next day" as a period unit. Of course there are such use cases (and timedelta(1) can satisfy those use cases), but the current timedelta (as it behaves in arithmetic with tz-aware datetimes) is a hybrid that is not coherent considered either as a Period or a Duration. "Satisfying some use cases sometimes" is not sufficient for correctness; conceptual coherency matters too.
Timedelta can only be considered a "Period object in units of days" if one accepts that the things it calls "hours", "minutes", and "seconds" are not really hours, minutes, or seconds, but rather fractional units of the "day-as-same-time-next-day" period that often (but not always) correspond to real hours, minutes, and seconds. I don't think this is a tenable explanation (and no one has attempted it), but you've just shown that it's one possible conclusion from defending the current model.
Tim's valiant efforts notwithstanding, I don't think there is any coherent conceptual model that justifies the current behavior of timedelta. The _implementation_ can easily be explained of course (and Tim has done so very clearly, many times - I'd summarize it as "all arithmetic temporarily pretends all datetimes are naive, and then blindly reattaches the original tzinfo member"), but in terms of the underlying concepts, it makes no sense.
In order to defend the current model as coherent, one has to discard one of the following points, and (despite having read every message in all the related threads), I am still not clear precisely which one of these Tim et al consider untrue or expendable:
1) A datetime with a tzinfo member that carries both a timezone and a specific UTC offset within that timezone (e.g. a pytz timezone instance) corresponds precisely and unambiguously to a single instant in astronomical time (as well as carrying additional information).
2) A timedelta object is clearly a Duration, not a Period, because timedelta(days=1), timedelta(hours=24), and timedelta(seconds=86400) result in indistinguishable objects. I think this point is uncontroversial; Tim has said several times that a timedelta is just a complicated representation of an integer number of microseconds. That's a Duration.
3) If one has two datetime objects that each unambiguously correspond to an instant in real time, and one subtracts them and gets back an object which represents a Duration in real microseconds, the only reasonable content for that Duration is the elapsed microseconds in real time between the two instants.
Much virtual ink has been spilled over whether the behavior of "datetime + timedelta(days=1)" is correct, but this is an intentionally muddying case to consider, because there _are_ two perfectly reasonable interpretations of "add one day to a datetime". It's just that one of those interpretations (the Period one), which has been used to justify the current model, is inconsistent with _everything else_ about the behavior and implementation of timedelta.
To be clear, I'm not arguing that this behavior can now be changed in the existing library objects in a backwards-incompatible way. But accepting that it is lacking in internal coherence (rather than just being an "alternative and equally good model") would be useful in clarifying what kind of an implementation we actually want (IMO, something very much like JodaTime/NodaTime). And then can we figure out how to get there from here.