After struggling for a while to determine how to convert from one timezone to another in Python I thought I'd write a quick little guide on it. Even if the only person it helps is me a few months from now I'll consider it a success!
It all started when I received the error
ValueError: Not naive datetime (tzinfo is already set). A little bit later I received the error
ValueError: astimezone() cannot be applied to a naive datetime. It was about this time that I realized I needed to learn what was actually going on.
The naive datetime
Datetimes in Python can either be
Aware. A naive datetime is a datetime that doesn't know its own timezone. It could be in
UTC, it could be in
US/Eastern, but it doesn't know. All it knows is which date and time that it has.
import datetime date = datetime.datetime(2015, 11, 11, 11, 0) date.tzinfo # None date.strftime("%a %b %d %H:%M:%S %Y") # Wed Nov 11 13:00:00 2015
At this point we don't know if it is 11AM EST, UTC... it is up for the programmer to keep track of which timezone they are working in.
Making it aware
To make our naive datetime aware of its timezone, we can use the
pytz library. Let's make our date be in UTC time. We'll do this by using the
localize method of a timezone.
import pytz utc = pytz.timezone('UTC') aware_date = utc.localize(date) aware_date.tzinfo # <UTC> aware_date.strftime("%a %b %d %H:%M:%S %Y") # Wed Nov 11 13:00:00 2015
Converting to another timezone
Now let's take our aware date (in UTC) and convert it to a date in the US/Eastern timezone. To do this we can again use
pytz along with a method of
eastern = pytz.timezone('US/Eastern') eastern_date = aware_date.astimezone(eastern) eastern_date.tzinfo # <DstTzInfo 'US/Eastern' EST-1 day, 19:00:00 STD> eastern_date.strftime("%a %b %d %H:%M:%S %Y") # Wed Nov 11 08:00:00 2015
Wrapping things up
We started with a naive date which was unaware of which timezone it was in. We made it aware by localizing it to the UTC timezone, and then we took that aware date and converted it into the US/Eastern timezone.