Why does datetime.timedelta only have the attributes 'days' and 'seconds'?

Loris Bennett loris.bennett at fu-berlin.de
Tue Apr 19 07:11:53 EDT 2022


"Peter J. Holzer" <hjp-python at hjp.at> writes:

> On 2022-04-16 20:35:22 -0000, Jon Ribbens via Python-list wrote:
>> On 2022-04-16, Peter J. Holzer <hjp-python at hjp.at> wrote:
>> > On 2022-04-16 14:22:04 -0000, Jon Ribbens via Python-list wrote:
>> >> ... although now having looked into the new 'zoneinfo' module slightly,
>> >> it really should have a giant red flashing notice at the top of it
>> >> saying "BEWARE, TIMEZONES IN PYTHON ARE UTTERLY BROKEN, NEVER USE THEM".
>> >>
>> >> Suppose we do this:
>> >>
>> >>     >>> import datetime, zoneinfo
>> >>     >>> LOS_ANGELES = zoneinfo.ZoneInfo('America/Los_Angeles')
>> >>     >>> UTC = zoneinfo.ZoneInfo('UTC')
>> >>     >>> d = datetime.datetime(2020, 10, 31, 12, tzinfo=LOS_ANGELES)
>> >>     >>> print(d)
>> >>     2020-10-31 12:00:00-07:00
>> >>     >>> d1 = d + datetime.timedelta(days=1)
>> >>     >>> print(d1)
>> >>     2020-11-01 12:00:00-08:00
>> >>
>> >> d1 is *wrong*.
>> >
>> > No, this is correct. That's the result you want.
>> 
>> I can categorically guarantee you it is not. But let's put it a
>> different way, if you like, if I want to add 24 hours, i.e. 86,400
>> seconds (or indeed any other fixed time period), to a timezone-aware
>> datetime in Python, how do I do it?
>
> What you *should* be able to do is use datetime.timedelta(hours=24).
>
> Unfortunately, you can't, because somebody decided to add a
> normalization rule to timedelta which turns this into timedelta(days=1,
> hours=0).
>
>> It would appear that, without converting to UTC before doing the
>> calculation, you can't.
>
> When doing calculations of this kind I frankly prefer converting to
> "seconds since the epoch" and doing simple arithmetic. (Yes, leap
> seconds, I know .. I just ignore those)
>
>
>> > So why didn't this work for me (I also used Python 3.9)? My guess is
>> > that astimezone() doesn't pick the correct time zone.
>> 
>> astimezone() doesn't pick a time zone at all. It works out the current
>> local offset from UTC.
>
> The timezone object it returns also includes a timezone string ("CET" in
> my example). So it's not *just* the offset. The result is misleading,
> though. You get something which looks like it's a timezone object for
> Central European Time, but isn't.
>
>> It doesn't know anything about when or if that
>> offset ever changes.
>
> astimezone() doesn't have to. It just has to pick the correct timezone
> object. That object then knows about offset changes.
>
>
>> >> timedelta(days=1) is 24 hours (as you can check by
>> >> calling timedelta(days=1).total_seconds() ),
>> >
>> > It shouldn't be. 1 Day is not 24 hours in the real world.
>> 
>> Nevertheless, timedelta is a fixed time period so that is the only
>> definition possible.
>
> Yeah, you keep repeating that. I think we are talking at cross-purposes
> here. You are talking about how timedelta is implemented while I'm
> talking what semantics it *should* have.
>
>
>> >> It appears that with Python it's not so much a guideline as an
>> >> absolute concrete rule, and not because programmers will introduce
>> >> bugs, but because you need to avoid bugs in the standard library!
>> >
>> > As a programmer you must always adapt to the problem. Saying "I must do
>> > it the wrong way because my library is buggy" is just lazy.
>> 
>> I didn't say any of that. I said you must do it the conservative way,
>> and it's not "my library" that's buggy, it's the language's built-in
>> *standard library* that's buggy.
>
> With "your library" I meant "the library you have" not "the library you
> wrote". And while having a buggy (or just badly designed) standard
> library is especially annoying, you still aren't forced to use it if if
> doesn't fit your needs. 
>
>         hp

I now realise that timedelta is not really what I need.  I am interested
solely in pure periods, i.e. numbers of seconds, that I can convert back
and forth from a format such as

  11-22::44:55

(These are the lengths of time a job has run on an HPC system - leap
seconds and time zones are of no relevance).

It is obviously fairly easy to rustle up something to do this, but I am
surprised that this is not baked into Python (such a class also seems to
be missing from R).  I would have thought that periods crop up all over
the place and therefore formatting as strings and parsing of string
would be supported natively by most modern languages.  Apparently not.

Cheers,

Loris

-- 
This signature is currently under construction.


More information about the Python-list mailing list