from datetime import datetime, timedelta
from zoneinfo import ZoneInfo
chi = ZoneInfo("America/Chicago")
nyc = ZoneInfo("America/New_York")
dt1 = datetime(2024, 3, 10, 3, 30, tzinfo=chi)
dt2 = datetime(2024, 3, 10, 2, 30, tzinfo=chi)
print(dt1 == dt1.astimezone(nyc))
print(dt2 == dt2.astimezone(nyc))
Actual result:
True
False
Expected result:
True
True
Why is False returned in one of those cases? In both cases it's comparing the same datetime, only adjusted to a different zone.
The same thing also happens in the fold:
from datetime import datetime, timedelta
from zoneinfo import ZoneInfo
chi = ZoneInfo("America/Chicago")
nyc = ZoneInfo("America/New_York")
dt1 = datetime(2024, 11, 3, 2, 30, tzinfo=chi)
dt2 = datetime(2024, 11, 3, 1, 30, tzinfo=chi)
print(dt1 == dt1.astimezone(nyc))
print(dt2 == dt2.astimezone(nyc))
Python's datetime by design allows to create non-existing datetime, like 2:30 am on Mar 10 2024 Chicago time in your example. That's the root of the evil here. You cannot do a correct conversion to another tz without (silently) shifting to a valid datetime (3:30 am in this case). This shift is what's causing the comparison to be False in the second case. To illustrate, you can do a conversion roundtrip:
dt2converted to NY time converted back to Chicago time comes back with different (now valid) fields - 2 am became 3 am. Those times are not equal and the comparison correctly returns False.For completeness, here's what happens if you put this example on the other side of a DST transition, DST active to inactive:
You notice for
dt1, both Chicago and NY have the same wall time and UTC offset - but those datetimes fall on different sides of the "DST fold" since the time zones are not the same. NY time is ahead of Chicago's, so it's already experiencing Winter time, while Chicago is still on the Summer side. Therefore, the datetimes are not identical and the comparison returns False.