Reputation: 56282
How do you convert a Python time.struct_time
object into a datetime.datetime
object?
I have a library that provides the first one and a second library that wants the second one.
Upvotes: 345
Views: 263567
Reputation: 114943
Like this:
import time, datetime
st = time.localtime()
dt = datetime.datetime(*st[:6])
print(dt)
which prints 2009-11-08 20:32:35
.
Update: if you want to include any timezone information from the struct_time
value, you could use this method:
def datetime_of_struct_time(st: time.struct_time) -> datetime.datetime:
"Convert a struct_time to datetime maintaining timezone information when present"
tz = None
if st.tm_gmtoff is not None:
tz = datetime.timezone(datetime.timedelta(seconds=st.tm_gmtoff))
# datetime doesn't like leap seconds so just truncate to 59 seconds
if st.tm_sec in {60, 61}:
return datetime.datetime(*st[:5], 59, tzinfo=tz)
return datetime.datetime(*st[:6], tzinfo=tz)
Which could be used with the struct_time
value from above:
print(datetime_of_struct_time(st))
printing 2009-11-08 20:32:35-04:00
.
Upvotes: 146
Reputation: 1806
This is not a direct answer to your question (which was answered pretty well already). However, having had times bite me on the fundament several times, I cannot stress enough that it would behoove you to look closely at what your time.struct_time object is providing, vs. what other time fields may have.
Assuming you have both a time.struct_time object, and some other date/time string, compare the two, and be sure you are not losing data and inadvertently creating a naive datetime object, when you can do otherwise.
For example, the excellent feedparser module will return a "published" field and may return a time.struct_time object in its "published_parsed" field:
time.struct_time(
tm_year=2013, tm_mon=9, tm_mday=9,
tm_hour=23, tm_min=57, tm_sec=42,
tm_wday=0, tm_yday=252, tm_isdst=0,
)
Now note what you actually get with the "published" field.
Mon, 09 Sep 2013 19:57:42 -0400
By Stallman's Beard! Timezone information!
In this case, the lazy man might want to use the excellent dateutil module to keep the timezone information:
from dateutil import parser
dt = parser.parse(entry["published"])
print "published", entry["published"])
print "dt", dt
print "utcoffset", dt.utcoffset()
print "tzinfo", dt.tzinfo
print "dst", dt.dst()
which gives us:
published Mon, 09 Sep 2013 19:57:42 -0400
dt 2013-09-09 19:57:42-04:00
utcoffset -1 day, 20:00:00
tzinfo tzoffset(None, -14400)
dst 0:00:00
One could then use the timezone-aware datetime object to normalize all time to UTC or whatever you think is awesome.
Upvotes: 45
Reputation: 10409
Use time.mktime() to convert the time tuple (in localtime) into seconds since the Epoch, then use datetime.fromtimestamp() to get the datetime object.
from datetime import datetime
from time import mktime
dt = datetime.fromtimestamp(mktime(struct))
Upvotes: 446