So I have the following code:
import pytz
from datetime import datetime
tz = pytz.timezone('Asia/Singapore')
original_time = tz.localize(datetime.now())
original_epoch = original_time.timestamp()
converted_dt = tz.localize(datetime.utcfromtimestamp(original_epoch))
converted_epoch = converted_dt.timestamp()
print('{}\t\t{}'.format(original_time, original_epoch))
print('{}\t\t{}'.format(converted_dt, converted_epoch))
And it spits out
# Original Time Original Epoch
2018-07-16 02:17:41.583510+08:00 1531678661.58351
2018-07-15 18:17:41.583510+08:00 1531649861.58351
# Converted Time Converted Epoch
Is this a Python bug or am I simply missing something? And either way, how can I convert datetime to epoch and back with confidence that I am getting back the right time?
tz.localize()
does not perform any timezone adjustments to the given datetime
; it just sets its tzinfo
to the given timezone. For the timestamps you're using, this means that tz.localtime()
performs the following:
datetime.now() -> tz.localize(datetime.now())
2018-07-16 02:17:41.583510 2018-07-16 02:17:41.583510+08:00
datetime.utcfromtimestamp(original_epoch) -> tz.localize(datetime.utcfromtimestamp(original_epoch))
2018-07-15 18:17:41.583510 -> 2018-07-15 18:17:41.583510+08:00
Note that the times don't change; only the timezone offset does. Because the inputs to tz.localize()
are two different naïve times, you get two different aware times out.
The correct way to construct a datetime
from a UNIX timestamp and a timezone is to use datetime.fromtimestamp()
with two arguments:
>>> print(datetime.fromtimestamp(1531678661.58351, pytz.timezone('Asia/Singapore')))
2018-07-16 02:17:41.583510+08:00