0

As far as I understood ZoneInfo in python 3.9 fixes the issue of "The year of 2038" problem with DST time issue. But I can see that the timedelta is wrong. Below it should have been 2 hours, not 3. What is wrong?

from zoneinfo  import ZoneInfo
import datetime
dt = datetime.datetime(2038,3,14,0,0, tzinfo = ZoneInfo(r'America/New_York'))
print(dt)           
dt2 = datetime.datetime(2038,3,14,3,0, tzinfo = ZoneInfo(r'America/New_York'))
print(dt2-dt)
guyguyguy12345
  • 539
  • 3
  • 11
  • 1
    `timedelta`s in Python show *wall time difference* if you're working with aware datetime. Between your example datetimes, there is a wall time difference of three hours although absolute time difference is only two hours (DST transition). More explanation can be found in [this blog article](https://blog.ganssle.io/articles/2018/02/aware-datetime-arithmetic.html) by Paul Ganssle. Btw. this is not specific to the 2k38 problem (completely different story, see int32...) – FObersteiner May 12 '21 at 08:36
  • How do I get absolute time difference instead of wall time difference? – guyguyguy12345 May 12 '21 at 14:12
  • 1
    I'd convert to UTC; `print(dt2.astimezone(ZoneInfo('UTC')) - dt.astimezone(ZoneInfo('UTC')))` (most clear / readable option I think). – FObersteiner May 12 '21 at 14:17
  • Can you make your comment as answer so I can accept it? – guyguyguy12345 May 12 '21 at 15:10

2 Answers2

1
from zoneinfo  import ZoneInfo
import datetime
dt = datetime.datetime(2038,3,14,0,0, tzinfo = ZoneInfo(r'America/New_York'))
print(dt)           # Output: 2038-03-14 00:00:00-05:00
dt2 = datetime.datetime(2038,3,14,3,0, tzinfo = ZoneInfo(r'America/New_York'))
print(dt2)          # Output: 2038-03-14 03:00:00-04:00
timedelta = dt2-dt1
print(timedelta)    # Output: 3:00:00

The above is correct because it is made aware of the DST, aka in the DST aware context. For example, if you add 3 hours to 2038-03-14 00:00:00-05:00 like the code below, you get a consistent result:

from zoneinfo  import ZoneInfo
import datetime
dt = datetime.datetime(2038,3,14,0,0, tzinfo = ZoneInfo(r'America/New_York'))
print(dt)                                      # Output: 2038-03-14 00:00:00-05:00
print(dt+datetime.timedelta(hours=3))          # Output: 2038-03-14 03:00:00-04:00

However, your thinking of 2 hours time difference is correct in the NO-DST-AWARE context, as shown below:

from zoneinfo  import ZoneInfo
import datetime
dt = datetime.datetime(2038,3,14,0,0, tzinfo = ZoneInfo(r'America/New_York'))
print(dt)           # Output: 2038-03-14 00:00:00-05:00
dt2 = datetime.datetime(2038,3,14,3,0, tzinfo = ZoneInfo(r'America/New_York'))
print(dt2)          # Output: 2038-03-14 03:00:00-04:00
dt_isoformat = dt.isoformat() 
print(dt_isoformat) # Output: 2038-03-14T00:00:00-05:00
dt2_isoformat = dt2.isoformat() 
print(dt2_isoformat) # Output: 2038-03-14T03:00:00-04:00
print(datetime.datetime.fromisoformat(dt2_isoformat)-datetime.datetime.fromisoformat(dt_isoformat)) # Output: 2:00:00
kayuapi_my
  • 498
  • 1
  • 6
  • 9
  • 1
    the code sample for the "NO-DST-AWARE context" is kind of convoluted I think; it's easier to just convert to UTC (see my comment under the question). – FObersteiner May 12 '21 at 14:24
0

I think It’s 3 hours, from 00 (which is 12) to 3 that’s absolutely 3 hours.

  • note that there is a DST transition between those date/time instances in the shown time zone. see also my comment under the question. – FObersteiner May 12 '21 at 08:39