Maybe this is a 4am bug, but I think I'm doing everything right, but it doesn't appear as though DST is translating from the UTC timestamp to the localized datetime.
>>> from datetime import datetime
>>> import pytz
>>> eastern = pytz.timezone("US/Eastern")
>>> utc = pytz.utc
>>> local_now = eastern.localize(datetime.now())
>>> utc_now = local_now.astimezone(utc)
>>> seconds = int(utc_now.strftime("%s"))
>>> utc_then = utc.localize(datetime.fromtimestamp(seconds))
>>> local_then = utc_then.astimezone(eastern)
>>> print utc_now, utc_then
2013-06-16 10:05:27.893005+00:00 2013-06-16 11:05:27+00:00
>>> print local_now, local_then
2013-06-16 06:05:27.893005-04:00 2013-06-16 07:05:27-04:00
o------------o
| | DT.datetime.utcfromtimestamp (*)
| |<-----------------------------------o
| | |
| datetime | |
| | DT.datetime.fromtimestamp |
| |<----------------------------o |
| | | |
o------------o | |
| ^ | |
.timetuple | | | |
.utctimetuple | | DT.datetime(*tup[:6]) | |
v | | |
o------------o o------------o
| |-- calendar.timegm (*) -->| |
| | | |
| |---------- time.mktime -->| |
| timetuple | | timestamp |
| |<-- time.localtime -------| |
| | | |
| |<-- time.gmtime (*)-------| |
o------------o o------------o
(*) Interprets its input as being in UTC and returns output in UTC
As the diagram shows, when you have a datetime in UTC such as utc_now
, to get its timestamp, use
seconds = calendar.timegm(utc_date.utctimetuple())
When you have a timestamp, to get to the datetime in UTC, use
DT.datetime.utcfromtimestamp(seconds)
import datetime as DT
import pytz
import calendar
eastern = pytz.timezone("US/Eastern")
utc = pytz.utc
now = DT.datetime(2013, 6, 16, 10, 0, 0)
local_now = eastern.localize(now)
utc_now = local_now.astimezone(utc)
seconds = calendar.timegm(utc_now.utctimetuple())
print(seconds)
# 1371391200
utc_then = utc.localize(DT.datetime.utcfromtimestamp(seconds))
local_then = utc_then.astimezone(eastern)
print utc_now, utc_then
# 2013-06-16 14:00:00+00:00 2013-06-16 14:00:00+00:00
print local_now, local_then
# 2013-06-16 10:00:00-04:00 2013-06-16 10:00:00-04:00
PS. Note that the timetuple()
and utctimetuple()
methods drop microseconds off the datetime. To convert a datetime to a timestamp in a way that preserves microseconds, use mata's solution.