views:

10547

answers:

7

How do I convert a datetime string in local time to a string in UTC time?

I'm sure I've done this before, but can't find it and SO will hopefully help me (and others) do that in future.

Clarification: For example, if I have "2008-09-17 14:02:00" in my local timezone (+10), I'd like to generate a string with the equivalent UTC time: "2008-09-17 04:02:00".

+9  A: 
def local_to_utc(t):
    """Make sure that the dst flag is -1 -- this tells mktime to take daylight
    savings into account"""
    secs = time.mktime(t)
    return time.gmtime(secs)

def utc_to_local(t):
    secs = calendar.timegm(t)
    return time.localtime(secs)

Source: http://feihonghsu.blogspot.com/2008/02/converting-from-local-time-to-utc.html

treefrog
If your source is a datetime.datetime object `t`, call as: local_to_utc(t.timetuple())
bd808
+7  A: 

First, parse the string into a naive datetime object. This is an instance of datetime.datetime with no attached timezone information. See documentation for datetime.strptime for information on parsing the date string.

Use the pytz module, which comes with a full list of time zones + UTC. Figure out what the local timezone is, construct a timezone object from it, and manipulate and attach it to the naive datetime.

Finally, use datetime.astimezone() method to convert the datetime to UTC.

Source code, using local timezone "America/Los_Angeles", for the string "2001-2-3 10:11:12":

import pytz, datetime
local = pytz.timezone ("America/Los_Angeles")
naive = datetime.datetime.strptime ("2001-2-3 10:11:12", "%Y-%m-%d %H:%M:%S")
local_dt = naive.replace (tzinfo = local)
utc_dt = local_dt.astimezone (pytz.utc)

From there, you can use the strftime() method to format the UTC datetime as needed:

utc_dt.strftime ("%Y-%m-%d %H:%M:%S")
John Millikin
+13  A: 

Thanks @rofly, the full conversion from string to string is as follows:

time.strftime("%Y-%m-%d %H:%M:%S", 
              time.gmtime(time.mktime(time.strptime("2008-09-17 14:04:00", 
                                                    "%Y-%m-%d %H:%M:%S"))))

My summary of the time/calendar functions:

time.strptime
string --> tuple (no timezone applied, so matches string)

time.mktime
local time tuple --> seconds since epoch (always UTC, so current timezone has been subtracted)

time.gmtime
seconds since epoch --> tuple in UTC

and

calendar.timegm
tuple in UTC --> seconds since epoch

time.localtime
seconds since epoch --> tuple in local timezone

Tom
A: 

How about -

time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime(seconds))

if seconds is None then it converts the local time to UTC time else converts the passed in time to UTC

A: 

Use the datetime module's utcnow() function.

>>> import datetime
>>> utc_datetime = datetime.datetime.utcnow()
>>> utc_datetime.strftime("%Y-%m-%d %H:%M:%S")
'2010-02-01 06:59:19'
monkut
That only converts the current time, I need to take any given time (as a string) and convert to UTC.
Tom
+1  A: 

if you prefer datetime.datetime:

dt = datetime.strptime("2008-09-17 14:04:00","%Y-%m-%d %H:%M:%S")
utc_struct_time = time.gmtime(time.mktime(dt.timetuple()))
utc_dt = datetime.fromtimestamp(time.mktime(utc_struct_time))
print dt.strftime("%Y-%m-%d %H:%M:%S")
Sure, but I can't see why you'd prefer that. It requires an extra import and 3 more function calls than my version...
Tom