0

I want to convert from a datetime in America/New_York to a UTC datetime. As I understand it, America/New_York is currently equivalent to UTC-4. This means that Mon Oct 10 12:30:00 2022 (America/New_York) should convert to Mon Oct 10 16:30:00 2022 (UTC).

Why is pytz reporting 17:26:00 instead?

import pytz
from pytz import timezone
from datetime import datetime

utc = timezone('UTC')
nyc = timezone('America/New_York')

dt = datetime(2022, 10, 10, 12, 30, tzinfo = nyc)

print(dt.ctime())

dt_utc = utc.normalize(dt)

print(dt_utc.ctime())

enter image description here

FObersteiner
  • 22,500
  • 8
  • 42
  • 72
Alecto Irene Perez
  • 10,321
  • 23
  • 46

1 Answers1

0

A careful reading of the pytz documentation yields this condensed information:

  1. This library only supports two ways of building a localized time. The first is to use the localize() method provided by the pytz library. This is used to localize a naive datetime (datetime with no timezone information). The second way of building a localized time is by converting an existing localized time using the standard astimezone() method.
  2. Unfortunately using the tzinfo argument of the standard datetime constructors ‘’does not work’’ with pytz for many timezones. It is safe for timezones without daylight saving transitions though, such as UTC. The preferred way of dealing with times is to always work in UTC, converting to localtime only when generating output to be read by humans.

This suggests that you should be converting from UTC to America/New_York, not the other way around, using astimezone:

from pytz import timezone
from datetime import datetime

utc = timezone('UTC')
nyc = timezone('America/New_York')

dt_utc = datetime(2022, 10, 10, 17, 30, tzinfo=utc)
print(dt_utc)
dt_nyc = dt_utc.astimezone(nyc)
print(dt_nyc)

print('-------------------------')

dt_utc = utc.localize(datetime(2022, 10, 10, 17, 30))
print(dt_utc)
dt_nyc = nyc.localize(datetime(2022, 10, 10, 13, 30))
print(dt_nyc)
print(dt_utc == dt_nyc)

Prints:

2022-10-10 17:30:00+00:00
2022-10-10 13:30:00-04:00
-------------------------
2022-10-10 17:30:00+00:00
2022-10-10 13:30:00-04:00
True
Booboo
  • 38,656
  • 3
  • 37
  • 60
  • What if `datetime(2022, 10, 10, 17, 30)` originates from 'America/New_York', not UTC? I think the point here is that pytz requires you to use `localize` to set a timezone. Yes you can set UTC directly, but that doesn't mean you always have to do that first. Besides, [UTC is no silver bullet either](https://codeblog.jonskeet.uk/2019/03/27/storing-utc-is-not-a-silver-bullet/). – FObersteiner Mar 29 '23 at 06:54
  • @FObersteiner My point number 1 says that you start with `localize` and once you have a localized `datetime` you *could* convert it to another timezone. Point number 2 says that doing something like `datetime(2022, 10, 10, 17, 30, tzinfo=nyc)` may not work ( even though in my example above it did). I did not mean to imply by showing an example of where I created a UTC `datetime` with `localize` and then used `astimezone` to convert to New York time it was the only way of getting a New York `datetime`, but according to `pytz`'s own documentation, which I quote verbatim, it is the preferred way. – Booboo Mar 29 '23 at 10:19