There are number of posts in the "Internets" on how to convert timestamp to datetime. But all of them are either mistaken or consider converting timestamp to local timezoned datetime object.
The correct (and awfully akward) mean to convert timestamp to UTC datetime object:
from datetime import datetime
from time import mktime, timezone
def utcdatetime_to_ts(dt):
return mktime(dt.utctimetuple()) - timezone
Then you can always:
assert utcdatetime_to_ts(datetime.utcnow()) - time() <= 1
Check also a better and shorter version in the comments.
5 комментариев:
Your assertion will most likely fail, since the resolution of time tuples is 1 second, and time.time() in your assertion most likely has much higher resolution.
Also, you could just do calendar.timegm(dt.utctimetuple()), and have a function that works for non-UTC datetimes as well.
I don't think this code is correct.
>>> datetime.datetime.fromtimestamp(1000000000)
datetime.datetime(2001, 9, 9, 3, 46, 40)
>>> calendar.timegm(datetime.datetime(2001, 9, 9, 3, 46, 40).utctimetuple())
1000007200
>>> mktime(datetime.datetime(2001, 9, 9, 3, 46, 40).utctimetuple())-timezone
1000007200.0
My local timezone is Europe/Vilnius. time.timezone is -3600 in summer, and -7200 in winter (which implies that it's never correct to add or subtract the current offset because it may not match the one that was correct for your particular datetime object).
This appears to work right, but I haven't tested it with many values or with different timezones (or with datetime objects with a timezone set):
>>> mktime(datetime.datetime(2001, 9, 9, 3, 46, 40).timetuple())
1000000000.0
Timezones are hard.
Marius, you've used fromtimestamp instead of utcfromtimestamp, that is why you've found the discrepancy.
>>> datetime.datetime.utcfromtimestamp(1000000000)
datetime.datetime(2001, 9, 9, 1, 46, 40)
>>> calendar.timegm(datetime.datetime(2001, 9, 9, 1, 46, 40).utctimetuple())
1000000000
>>>
>>> mktime(datetime.datetime(2001, 9, 9, 1, 46, 40).utctimetuple()) - timezone
1000000000.0
Careful, it looks like you've imported the timezone (an int) so it'll freeze to whatever timezone you're in when the program starts. For long-running processes, this can be a problem.
Wow, Tim, thanks! I didnt even aware of this problem!
So, solution by Tuure Laurinolli is the best:
calendar.timegm(dt.utctimetuple())
Отправить комментарий