On 2022-04-16 20:35:22 -0000, Jon Ribbens via Python-list wrote: > On 2022-04-16, Peter J. Holzer <hjp-pyt...@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 -- _ | 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