3
votes

From http://docs.python.org/library/time.html:

time.mktime(t): This is the inverse function of localtime(). Its argument is the struct_time or full 9-tuple (since the dst flag is needed; use -1 as the dst flag if it is unknown) which expresses the time in local time, not UTC. It returns a floating point number, for compatibility with time(). If the input value cannot be represented as a valid time, either OverflowError or ValueError will be raised (which depends on whether the invalid value is caught by Python or the underlying C libraries). The earliest date for which it can generate a time is platform-dependent.

This says you need to specify your time tuple in local time, not UTC. However, I want to specify in UTC; I don't want to use the local time zone on the box.

Is there any way that I can go from datetime to a timestamp, where the time is treated as UTC? I want to be able to keep everything in a normalized UTC form (datetime object) when I convert to and from timestamps.

I want to be able to do something like this and have x and y come out the same:

 y = datetime.datetime.utcfromtimestamp(time.mktime(x.timetuple()))
 x = dateutil.parser.parse('Wed, 27 Oct 2010 22:17:00 GMT')
 stamp = time.mktime(x.timetuple())
 y = datetime.datetime.utcfromtimestamp(stamp)
 x
datetime.datetime(2010, 10, 27, 22, 17, tzinfo=tzutc())
 y
datetime.datetime(2010, 10, 28, 6, 17)
2

2 Answers

5
votes

I think you are looking for calendar.timegm:

import datetime
import dateutil.parser
import calendar

x = dateutil.parser.parse('Wed, 27 Oct 2010 22:17:00 GMT')
stamp = calendar.timegm(x.timetuple())
y = datetime.datetime.utcfromtimestamp(stamp)
print(repr(x))
# datetime.datetime(2010, 10, 27, 22, 17, tzinfo=tzutc())

print(repr(y))
# datetime.datetime(2010, 10, 27, 22, 17)
0
votes

email package from stdlib can parse the time string in rfc 5322 format (previously rfc 2822, rfc 822):

#!/usr/bin/env python
from datetime import datetime, timedelta
from email.utils import mktime_tz, parsedate_tz

time_tuple = parsedate_tz('Wed, 27 Oct 2010 22:17:00 GMT')
posix_timestamp = mktime_tz(time_tuple)  # integer
utc_time = datetime(*time_tuple[:6])     # naive datetime object
assert utc_time == (datetime(1970, 1, 1) + timedelta(seconds=posix_timestamp))

See Python: parsing date with timezone from an email.

To convert a naive datetime object that represents time in UTC to POSIX timestamp:

posix_timestamp = (utc_time - datetime(1970, 1, 1)).total_seconds()

See Converting datetime.date to UTC timestamp in Python.