On 2022-04-17 06:08:54 +1000, Chris Angelico wrote: > On Sun, 17 Apr 2022 at 03:37, Peter J. Holzer <hjp-pyt...@hjp.at> wrote: > > Datetime arithmetic in the real world is typically not done in seconds, > > but in calendaric units: Hours, days, weeks, months, years, ... > > The problem is that several of these have varying lengths: > > > > * 1 minute may be 60 or 61 seconds (theoretically also 59, but that > > hasn't happened yet). > > * 1 day can be 23, 24 or 25 hours (unless you are in Troll, Antarctica, > > where it's even weirder). > > I think Troll still only has days that consist of 23-25 hours; the > weird part is that they move their clocks forward for Oslo's summer, > which is their winter.
According to Wikipedia they switch between UTC+2 and UTC+0, so the switchover days would be 22 and 26 hours, respectively. > > Therefore a new class (provisionally called timedeltacal, because it is > > calendaric, not absolute) should be added to datetime: > > > > Internally it stores months, days, seconds and microseconds as ints. > > > > The seconds and microseconds split is mostly for compatibility with > > datetime and timedelta. We could store seconds as a float instead. > > > > We don't store minutes since leap seconds aren't usually represented in > > "computer time", so they are unlikely to be useful in a timedeltacal > > object. > > > > Days are stored since they aren't a fixed multiple of any smaller unit. > > Months are stored since they aren't a fixed multiple of any smaller unit. > > > > Hours, weeks and years aren't stored since they are always 60 minutes, 7 > > days and 12 months respectively. > > It sounds like you're planning for annual DST changes, but what about > other shifts? What about when a location adopts standard time, which > could change their UTC offset (yes, I'm aware that most places adopted > standard time before UTC was a thing, but we still usually call it a > UTC offset rather than messing with GMT-UTC changeover) by an > arbitrary amount, even minutes? Yes, I think you are right. I first thought it wouldn't matter because you'd have to look it up in the database anyway, but that's a non-sequitur. Clearly, when you cities switched from local times to timezones, one hour had to be longer or shorter than 3600 seconds. Similarily if India decided to switch to a whole-hour offset, then they would have one hour of 30 or 90 minutes. > It might be cleaner to simply have all of the arguments that datetime > has: year, month, day, hour, minute, second, microsecond (with the > possibility of merging second/usec into a single float). Yup. > > When adding a timedeltacal object to a datetime, the fields are added > > from most to least significant: First a new date is computed by > > advancing the number of months specified [TODO: Research how other > > systems handle overflow (e.g. 2022-01-31 + 1 month: 2022-02-31 doesn't > > exist)] > > Quick test in Pike: [...] > Subtracting seventeen days from today gets us to the 31st of March, > and adding one month to that gives us the 30th of April. Subtracting > eighteen days gets us to the 30th of March, and adding a month to that > _also_ gives us the 30th of April. Same for PostgreSQL. > > then advance the number of days. Finally add the number of > > seconds and microseconds, taking into accout daylight savings time > > switches if the datetime is time zone aware. > > Here's the local DST switchover: [results I expected] > > Subtracting a timedeltacal object from a datetime is the same, just in > > the opposite direction. > > > > Note that t + d - d is in general not equal to t. > > By "in general", do you mean "there will be some odd exceptions", or > "this is usually going to be unequal"? The former. > For instance, going back to the month boundary case, since it's not > possible for "add one month" from two different dates to give the same > result, obviously subtracting a month from that result can't give both > the originals. But for the most part, I would expect t + d - d to be > equal to t, modulo rounding error and possible DST corrections. > Crossing a DST boundary shouldn't break this pattern; only landing in > the actual gap/fold should cause issues. > Is that the intention? Yes, exactly. > > We can't cnange the semantics of datetime - datetime, so there must be a > > function to compute the difference between to datetimes as a > > timedeltacal. It could be a method on datetime (maybe t.sub(u) for t-u > > like in Go) or a constructor which takes two datetime objects. > > > > In any case I think that u + (t - u) == t should hold. [TODO: Check that > > this is possible] > > > > Isn't that the exact same thing as saying that t + d - d == t? No, because the overflow handling isn't reversible. Using the semantics from Pike or Postgres: 2022-03-31 + 1 month == 2022-04-30. But 2022-04-30 - 1 month == 2022-03-30. If "spill over" extra days (IIRC, PHP does that but I'd have to check) 2022-03-31 + 1 month == 2022-05-01 2022-05-01 - 1 month == 2022-04-01 So t + d - d is not always == t. (If you fix this special case you'll break some more common cases). But I think (but haven't yet proven) that for any pair of datetimes t0 and t1 there should always exist at least one delta d such that t0 + d == t1. 2022-03-31 + 30 days = 2022-04-30 2022-03-30 + 1 month = 2022-04-30 2022-03-31 + 31 days == 2022-05-01 2022-03-31 + 1 month + 1 day == 2022-05-01 2022-03-31 + 2 months - 30 days == 2022-05-01 Not sure which of the last three should be the canonical one. I can make an argument for each of them. > Or are you saying that, when you subtract two timestamps, you can > never get one of the odd exceptions that would cause problems? Because > I'd believe that; the net result would be that u+(t-u) == t, but > u+((t+d)-(u+d)) might not equal t. Putting it another way: Shift > invariance should *normally* hold, but there may be some exceptions at > month ends (basically rounding error when you add/subtract a month) > and DST switches. Yes. > When the time comes, if you need a hand putting together a PEP, feel > free to reach out to me. Thanks. hp -- _ | Peter J. Holzer | Story must make more sense than reality. |_|_) | | | | | h...@hjp.at | -- Charles Stross, "Creative writing __/ | http://www.hjp.at/ | challenge!"
signature.asc
Description: PGP signature
-- https://mail.python.org/mailman/listinfo/python-list