3

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)
Michael Currie
  • 13,721
  • 9
  • 42
  • 58
Alex Amato
  • 1,591
  • 4
  • 19
  • 32
  • 1
    [`timestamp = (x - datetime(1970, 1, 1, tzinfo=dateutil.tz.tzutc())).total_seconds()`](http://stackoverflow.com/a/8778548/4279) – jfs Jun 07 '13 at 19:43

2 Answers2

5

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)
unutbu
  • 842,883
  • 184
  • 1,785
  • 1,677
0

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.

Community
  • 1
  • 1
jfs
  • 399,953
  • 195
  • 994
  • 1,670