In Python, how do you convert seconds since epoch to a `datetime` object?
The time
module can be initialized using seconds since epoch:
>>> import time
>>> t1=time.gmtime(1284286794)
>>> t1
time.struct_time(tm_year=2010, tm_mon=9, tm_mday=12, tm_hour=10, tm_min=19,
tm_sec=54, tm_wday=6, tm_yday=255, tm_isdst=0)
Is there an elegant way to initialize a datet开发者_开发问答ime.datetime
object in the same way?
datetime.datetime.fromtimestamp
will do, if you know the time zone, you could produce the same output as with time.gmtime
>>> datetime.datetime.fromtimestamp(1284286794)
datetime.datetime(2010, 9, 12, 11, 19, 54)
or
>>> datetime.datetime.utcfromtimestamp(1284286794)
datetime.datetime(2010, 9, 12, 10, 19, 54)
Seconds since epoch to datetime
to strftime
:
>>> ts_epoch = 1362301382
>>> ts = datetime.datetime.fromtimestamp(ts_epoch).strftime('%Y-%m-%d %H:%M:%S')
>>> ts
'2013-03-03 01:03:02'
From the docs, the recommended way of getting a timezone aware datetime object from seconds since epoch is:
Python 3:
from datetime import datetime, timezone
datetime.fromtimestamp(timestamp, timezone.utc)
Python 2, using pytz
:
from datetime import datetime
import pytz
datetime.fromtimestamp(timestamp, pytz.utc)
Note that datetime.datetime.fromtimestamp(timestamp) and .utcfromtimestamp(timestamp) fail on windows for dates before Jan. 1, 1970 while negative unix timestamps seem to work on unix-based platforms. The docs say this:
"This may raise ValueError, if the timestamp is out of the range of values supported by the platform C gmtime() function. It’s common for this to be restricted to years in 1970 through 2038"
See also Issue1646728
For those that want it ISO 8601 compliant, since the other solutions do not have the T
separator nor the time offset (except Meistro's answer):
from datetime import datetime, timezone
result = datetime.fromtimestamp(1463288494, timezone.utc).isoformat('T', 'microseconds')
print(result) # 2016-05-15T05:01:34.000000+00:00
Note, I use fromtimestamp
because if I used utcfromtimestamp
I would need to chain on .astimezone(...)
anyway to get the offset.
If you don't want to go all the way to microseconds
you can choose a different unit with the
isoformat() method.
精彩评论