Timezones in Python
- I had a Python datetime object, T.
- I knew it was in Eastern time and wanted to convert to UTC.
- I also wanted it to keep track of daylight savings time, for when I have dates later in the year.
- Python datetime objects have “support” for timezone info, but you have to implement it yourself. Read: more coding overhead that I’m trying to avoid.
Here’s how to do it the easy way.
There’s a module called pytz to make things easy.
Import
First, import the goodies.
from pytz import timezone
import pytz
import datetime
Create timezone objects
Then, create two timezone objects: one for eastern time, and one for utc.
eastern_tz = timezone('US/Eastern')
utc_tz = pytz.utc
Localize the time
Next, “localize” the time, T. This is a way of telling the datetime object what timezone it should be.
T = datetime.datetime(2008, 1, 10, 7, 20, 46, 613195)
eastern_datetime = eastern_tz.localize(T)
# datetime.datetime(2008, 1, 10, 7, 20, 46, 613195,
# tzinfo=)
Convert the localized time
Now convert eastern_datetime into UTC using its astimezone method. Feed it the utc_tz timezone object to tell it how to convert.
utc_datetime = eastern_datetime.astimezone(utc_tz)
Plotting time series with timezones
The documentation for matplotlib says you can give plot_date() a string like ‘US/Eastern’ for the tz keyword. This didn’t work for me; I got errors.
: astimezone() argument 1 must be datetime.tzinfo, not str
WARNING: Failure executing file:
To fix this, I found my matplotlibrc file (the Linux command locate matplotlibrc gave me the file /usr/lib/python2.5/site-packages/matplotlib/mpl-data/matplotlibrc) and changed the timezone to “US/Eastern”.
date2num converts dates into number of days (fraction part represents hours, minutes, seconds) since 0001-01-01 00:00:00 UTC.
But plot_date pulls from matplotlibrc file to determine which timezone to show in.
That means, if you have a list of datetime objects that are in fact Eastern, you have to make sure they are converted via pytz, then date2num’d, then plotted.
You’ll also need to set the xdata formatter ax.fmt_xdata = DateFormatter(’%x %H:%M %Z’)
In sum, assume you have a list of datetime objects that are really in Eastern time. This list is called timeline.
timeline # a list of datetime objects that are really in Eastern
values # a list of values, one for each time in timeline
import pytz
from pytz import timezone
from pylab import figure, show, DateFormatter
eastern = timezone('US/Eastern')
utc = pytz.utc
timeline_eastern = [eastern.localize(i) for i in timeline]
timeline_utc = [i.astimezone(utc) for i in timeline_eastern]
# Both of these are the same! Why? Cause date2num is smart and
# keeps track of timezones. Nevertheless, these are both in "days from
# 0001-01-01 00:00 UTC"
mpl_dates_1 = [date2num(i) for i in timeline_eastern]
mpl_dates_2 = [date2num(i) for i in timeline_utc]
fig = figure()
ax = fig.add_subplot(111)
ax.plot_date(timeline,values)
# This formats numbers in the lower right to be proper dates
# that change when you mouse over the plot.
ax.fmt_xdata = DateFormatter('%x %H:%M %Z')
show()
The coolest part is if you plot a list of dates year round, the timezones change appropriately between EDT and EST!
Tags: daylight savings, eastern, timezone, tz, utc