1

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?

FObersteiner
  • 22,500
  • 8
  • 42
  • 72
foragerDev
  • 1,307
  • 1
  • 9
  • 22

2 Answers2

4

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
FObersteiner
  • 22,500
  • 8
  • 42
  • 72
-1

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.

vvg
  • 1,010
  • 7
  • 25
  • when I convert a naive time to New York and then to UTC, it should get the same from UTC when I convert it backward. but I am not getting it back same. – foragerDev Aug 26 '20 at 10:51
  • Please print the raw date in US format, TZ converted date (UTC) and TZ converted back (US). – vvg Aug 26 '20 at 10:57
  • You can see my outputs, are they varying Machine to Machine? – foragerDev Aug 26 '20 at 10:58
  • You have only two. Print the raw datetime also. – vvg Aug 26 '20 at 10:59
  • @vvgiri: check the blog post I linked in my answer to find out more about the 56 min difference (which happens to be there...) – FObersteiner Aug 26 '20 at 13:09
  • @vvg the time started out with `minutes=0` and ended up with `minutes=56`. That is definitely not "as intended". I think you have misread the question. – Ken Williams May 18 '21 at 21:56