Reputation: 1409
I am trying to convert time from America/New York to UTC and then converting it back to the New York time. But I get different results while doing with this with pytz
.
I am doing this:
new_date = parser.parse("May 4, 2021")
new_date = new_date.replace(tzinfo=pytz.timezone("America/New_York"))
date = new_date.astimezone(pytz.timezone("UTC"))
Output:
datetime.datetime(2021, 5, 4, 4, 56, tzinfo=<UTC>)
When I try to reconvert it back to the New York time I get this:
date.astimezone(pytz.timezone("America/New_York"))
I get:
datetime.datetime(2021, 5, 4, 0, 56, tzinfo=<DstTzInfo 'America/New_York' EDT-1 day, 20:00:00 DST>)
My Question is why there is 56 minute difference and what can be done to prevent this?
Upvotes: 2
Views: 1558
Reputation: 6613
I was able to do the conversion from Eastern to UTC and then back to Eastern without the 56 minutes showing up. (I also changed the date to 11-10 to see the time in Standard Time)
from datetime import datetime
import pytz
t = '2024-11-10 13:00:00'
dt = datetime.strptime(t, '%Y-%m-%d %H:%M:%S')
eastern = pytz.timezone('US/Eastern')
east_dt = eastern.localize(dt)
print('eastern', east_dt)
utc = east_dt.astimezone(pytz.utc)
print('utc', utc)
back = utc.astimezone(eastern)
print('back', back)
"""
eastern 2024-11-10 13:00:00-05:00
utc 2024-11-10 18:00:00+00:00
back 2024-11-10 13:00:00-05:00
"""
""" is daylight savings/standard time aware"""
Upvotes: 0
Reputation: 25634
The 56 min difference originates from the fact that the first entry in the database that pytz
accesses, refers to LMT (local mean time):
import pytz
t = pytz.timezone("America/New_York")
print(repr(t))
# <DstTzInfo 'America/New_York' LMT-1 day, 19:04:00 STD>
You can read more in P. Ganssle's Fastest Footgun blog post or in Weird timezone issue with pytz here on SO.
tl;dr - Never replace
a tzinfo with a timezone object from pytz
! Use localize
(or astimezone
) instead, to adjust the timezone to the year of the datetime object.
...But: since you use dateutil
already, why don't you use it here as well:
import dateutil
new_date = dateutil.parser.parse("May 4, 2021")
# you can safely replace with dateutil's tz objects:
new_date = new_date.replace(tzinfo=dateutil.tz.gettz("America/New_York"))
date = new_date.astimezone(dateutil.tz.UTC)
# date
# datetime.datetime(2021, 5, 4, 4, 0, tzinfo=tzutc())
date = date.astimezone(dateutil.tz.gettz("America/New_York"))
# date
# datetime.datetime(2021, 5, 4, 0, 0, tzinfo=tzfile('US/Eastern'))
print(date)
# 2021-05-04 00:00:00-04:00
Upvotes: 5
Reputation: 1213
The code is functioning as intended.
There is not a 56 minutes difference. There is a 4 hour difference.
datetime.datetime(
2021, // yyyy
5, // mm
4, // dd
4, // hh -- This is hours
56, // mi
tzinfo=)
4 hours also happens to be the hours by which UTC is ahead of US Eastern Time. When it is 00:56 Hrs in New York, in UTC time it will be 04:56 Hrs.
Upvotes: -1