In the below code:
from datetime import datetime import pytz EDT = pytz.timezone('US/Eastern') d1 = datetime.now(tz=EDT) d2 = datetime.combine(d1.date(), d1.time(), tzinfo=EDT)
Why are d1 and d2 showing different timezone information?
>> d1 datetime.datetime(2021, 4, 8, 7, 0, 44, 316514, tzinfo=<DstTzInfo 'US/Eastern' EDT-1 day, 20:00:00 DST>)
>> d2 datetime.datetime(2021, 4, 8, 7, 0, 44, 316514, tzinfo=<DstTzInfo 'US/Eastern' LMT-1 day, 19:04:00 STD>)
How do I get the same datetime as datetime.now
when using datetime.combine
?
Advertisement
Answer
datetime.now
effectively converts (localizes) your datetime with the pytz
timezone object – from the docs:
If tz is not None, it must be an instance of a tzinfo subclass, and the current date and time are converted to tz’s time zone.
datetime.combine does not do that. It is as if you would write something like datetime(2020,1,1, tzinfo=pytz.timezone('US/Eastern'))
– effectively not adjusting the time zone to the provided date/time. See also e.g. pytz localize vs datetime replace and pytz: The Fastest Footgun in the West for more background info.
The correct way to get d2
with pytz
would be
d2 = EDT.localize(datetime.combine(d1.date(), d1.time()))
No such issues if using timezone objects from dateutil
or zoneinfo
(Python 3.9+):
from datetime import datetime from zoneinfo import ZoneInfo EDT = ZoneInfo('US/Eastern') d1 = datetime.now(tz=EDT) d2 = datetime.combine(d1.date(), d1.time(), tzinfo=EDT) # d1 # Out[75]: datetime.datetime(2021, 4, 8, 7, 57, 18, 309209, tzinfo=zoneinfo.ZoneInfo(key='US/Eastern')) # d2 # Out[76]: datetime.datetime(2021, 4, 8, 7, 57, 18, 309209, tzinfo=zoneinfo.ZoneInfo(key='US/Eastern')) # d1 == d2 # Out[77]: True