Hi Tim, On 09/10/2015 08:41 PM, Tim Peters wrote: > It's become beyond obvious that I'll never be able to make enough time > to respond to all of these, so I'll address just this for now. because > it's impossible to make progress on anything unless there's agreement > on what technical terms mean: > > > [Carl Meyer <[email protected]>] >>>> If you are doing any kind of "integer arithmetic on POSIX timestamps", you >>>> are _always_ doing timeline arithmetic. > > [Tim] >>> True. > > [Carl] >>>> Classic arithmetic may be many things, but the one thing it definitively is >>>> _not_ is "arithmetic on POSIX timestamps." > > [Tim] >>> False. UTC is an eternally-fixed-offset zone. There are no >>> transitions to be accounted for in UTC. Classic and timeline >>> arithmetic are exactly the same thing in any eternally-fixed-offset >>> zone. Because POSIX timestamps _are_ "in UTC", any arithmetic >>> performed on one is being done in UTC too. Your illustration next >>> goes way beyond anything I could possibly read as doing arithmetic on >>> POSIX timestamps: > > [Carl] >> Translation: "I refuse to countenance the possibility of Model A." > > Not at all. I've tried several times to get it across in English, so > this time I'll try code instead: > > def dt_add(dt, td, timeline=False): > ofs = dt.utcoffset() > as_utc = dt.replace(tzinfo=timezone.utc) > > # and the following is identical to converting to > # a timestamp, "using POSIX timestamp arithmetic", > # then converting back to calendar notation > as_utc -= ofs > as_utc += td > > if timeline: > return as_utc.astimezone(dt.tzinfo) > else: # classic > return (as_utc + ofs).replace(tzinfo=dt.tzinfo)
Well, sure. Of course it is possible to use "arithmetic on POSIX timestamps" within an implementation of either kind of arithmetic, if you try hard enough; I've never said anything to the contrary (that would be a provably silly thing to say). What your code does make clear is that if you convert from a DST-using timezone to a POSIX timestamp, do "arithmetic on POSIX timestamps" and then do a normal (what you would in any other context call a "correct") conversion back to the first timezone afterwards, the result you get is timeline arithmetic. Sure, if you do a specific sort of weird (what you would in any other context call "wrong") conversion from the POSIX timestamp back to the other timezone afterward, then you can get classic arithmetic instead. I'm not sure what you think that demonstrates. I think it demonstrates that both timeline and classic arithmetic _can_ be described in terms that include "arithmetic on POSIX timestamps," but timeline arithmetic is much more naturally seen that way. Your original assertion was that "Classic arithmetic is equivalent to doing integer arithmetic on integer POSIX timestamps" as a justification for why datetime chose classic arithmetic, implying that classic arithmetic is somehow _more_ or _more naturally_ seen as "equivalent to integer arithmetic on integer POSIX timestamps" than timeline arithmetic. I found that assertion puzzling, and I still do. I'd still conclude the same thing I already said in an earlier reply: """ So, "timeline arithmetic is just arithmetic on POSIX timestamps" means viewing all aware datetimes as isomorphic to POSIX timestamps. "Classic arithmetic is just arithmetic on POSIX timestamps" means viewing aware datetimes as naive datetimes which one can pretend are in a hypothetical (maybe UTC, if you like) fixed-offset timezone which is isomorphic to actual POSIX timestamps (even though their actual timezone may not be fixed-offset). I accept that those are both true and useful in the implementation of their respective model. I just don't think either one is inherently obvious or useful as a justification of their respective mental models; rather, which one you find "obvious" just reveals your preferred mental model. """ > That adds an aware datetime to a timedelta, doing either classic or > timeline arithmetic depending on the optional flag. If you want to > claim this doesn't do either kind of arithmetic correctly, prove it > with a specific example I'm not sure why you'd think I'd have any issue with that code, or any desire to prove it wrong. [...] > I believe you have _pictured_ the POSIX timestamp number line > annotated with local calendar notations in your head, but those labels > have nothing to do with the timestamp arithmetic. It would be more accurate to say that a Model A view pictures only a single timeline, which is physical (Newtonian) time. A point on that timeline is an instant. Any given instant is annotated with any number of labels, each one a unique and unambiguous description of that instant in some labeling system. A labeling system can be very simple (e.g. POSIX timestamps), less simple (proleptic Gregorian in UTC, or to a lesser extent any fixed-offset timezone), or slightly ridiculous (timezones with folds and gaps, where now we need a `fold` attribute or an explicit offset at each instant or something similar to keep each label unique and unambiguous). This mental model implies (and requires) that all of these labeling systems are isomorphic to each other and to the physical-time timeline, and that arithmetic in any of them is isomorphic to arithmetic in any other (and is thus obviously timeline arithmetic). Really my only point in this entire thread has been that this model (contrary to some of the denigration of it on this mailing list) is actually quite intuitive, not difficult to teach, and possible to do all sorts of useful work in (_even_ when you have to also teach pytz's unfortunate API for it). If you can agree with that - great, we're done here. If you don't agree with that, we may as well still be done, because I have too much personal experience suggesting it to be true for you to be likely able to convince me otherwise :-) I've also come to recognize, through this thread, that Model B (where the "local clock time in a given timezone" "timeline" is elevated to sort-of-equal status with the physical timeline, rather than just considered a weird complex labeling system for physical time) is also useful (more useful for some tasks) and makes intuitive sense too. [...] > 1. The "as_utc -= ofs" line is theoretically impure, because it's > treating a local time _as if_ it were a UTC time. There's no real way > around that. We have to convert from local to UTC _somehow_, and > POSIX dodges the issue by providing mktime() to do that "by magic". > Here we're _inside_ the sausage factory, doing it ourselves. Some rat > guts are visible at this level. If you look inside a C mktime() > implementation, you'll find rat guts all over that too. This seems like a really hand-wavy rationalization of an operation that can only really be described as an incorrect timezone conversion. Of course that incorrect timezone conversion operation is useful for implementing classic arithmetic in the way you've implemented it, but taken out of that context it's just an incorrect conversion. The reason you _need_ that incorrect conversion is because for some reason you're really wanting to do your arithmetic in terms of POSIX timestamps (which are defined as being in UTC), but you don't _really_ want correct conversion to UTC and back (because if you do that, you'll get timeline arithmetic). > But it's no problem for Guido ;-) We just set the hands on a UTC > clock to match the local clock, then move the hands on the UTC clock > by the amount the local clock is "ahead of" or "behind" UTC. In that > way you can indeed picture the operation as being entirely "in UTC". Sure, you can, if you're motivated enough :-) > 2. This would be a foolish _implementation_ of classic arithmetic, but > not for semantic reasons. It's just grossly inefficient. Stare at > the code, and in the classic case it subtracts the UTC offset at first > only to add the same offset back later. Those cancel out, so there's > no _semantic_ need to do either.. It's only excessive concern for > theoretical purity that could stop one from spelling it as > > return dt + td > > from the start. That's technically absurd, since it's doing POSIX > timestamp arithmetic on a timestamp that's _not_ a UTC seconds count. > Its only virtue is that it gets the same answer far faster ;-) I actually think this implementation would be _less_ technically absurd. I'm not sure why you'd insist that any arithmetic on a count of seconds must be "POSIX timestamp arithmetic." In this case you're just doing integer arithmetic on a naive count of seconds since some point in the local timezone clock, rather than on a count of seconds in UTC. That's a much more natural way to view classic arithmetic, and also happens to be the way datetime actually does it (where "some point" is datetime(1, 1, 1)). Carl
signature.asc
Description: OpenPGP digital signature
_______________________________________________ Datetime-SIG mailing list [email protected] https://mail.python.org/mailman/listinfo/datetime-sig The PSF Code of Conduct applies to this mailing list: https://www.python.org/psf/codeofconduct/
