Pre-Pre-PEP: The datetime.timedeltacal class

Barry barry at barrys-emacs.org
Sat Apr 16 15:25:45 EDT 2022



> On 16 Apr 2022, at 18:38, Peter J. Holzer <hjp-python at hjp.at> wrote:
> 
> I intend to take this to python-ideas, but I'm not currently subscribed
> there and I think I should probably do a bit of research before
> proposing something over there. So I'll start by gathering some feedback
> here with a rough sketch.
> 
> 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).
> * 1 month may be 28, 29, 30 or 31 days (let's stick to the Gregorian
>  calendar)
> 
> The standard library has a datetime.timedelta class which does store
> days and seconds separately, so somebody seems to have had the right
> idea, but the normalization rules make it impossible to distinguish
> between "1 day plus 1 hour" and "25 hours", and it doesn't deal with
> months at all.
> 
> Technically it shouldn't be too hard to "fix" timedelta, but that
> wouldn't be backward compatible and would very likely break existing
> code.
> 
> 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.
> 
> 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)], 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.
> 
> 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.
> 
> 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]

Suggest that you start with the use cases that you want supported.
Then you can turn them into a set of tests to check that the solution works.

Barry

> 
>        hp
> 
> -- 
>   _  | Peter J. Holzer    | Story must make more sense than reality.
> |_|_) |                    |
> | |   | hjp at hjp.at         |    -- Charles Stross, "Creative writing
> __/   | http://www.hjp.at/ |       challenge!"
> -- 
> https://mail.python.org/mailman/listinfo/python-list


More information about the Python-list mailing list