I\'m attempting to craft a function that takes a time object and converts it to UTC time. The code below appears to be off by one hour. When i run noon through the converter,
To convert time in given timezone to UTC time:
from datetime import datetime
import pytz
def convert_to_utc(time, tzname, date=None, is_dst=None):
tz = pytz.timezone(tzname)
if date is None: # use date from current local time in tz
date = datetime.now(tz).date()
dt = tz.localize(datetime.combine(date, time), is_dst=is_dst)
return dt.astimezone(pytz.utc).time(), dt.utcoffset().total_seconds()
if is_dst
is None
it raises an exception for ambiguous local times.
To convert UTC time to local time in given timezone:
def convert_from_utc(time, tzname, date=None):
tz = pytz.timezone(tzname)
if date is None: # use date from current time in utc
date = datetime.utcnow().date()
dt = datetime.combine(date, time).replace(tzinfo=pytz.utc)
return tz.normalize(dt.astimezone(tz)).time()
time = datetime.strptime('12:00:00', "%H:%M:%S").time()
utc_time, offset = convert_to_utc(time, 'America/Chicago')
print utc_time.strftime("%H:%M:%S"), offset # -> 17:00:00 -18000.0
utc_time = datetime.strptime('17:00:00', "%H:%M:%S").time()
time = convert_from_utc(utc_time, 'America/Chicago')
print time.strftime("%H:%M:%S") # -> 12:00:00
In general it is preferable to work with full datetime
objects to avoid ambiguity with what is the correct date i.e., pass and return datetime
objects.
By using the replace
method on the datetime, you're not allowing the time zone to be adjusted for daylight savings time. Try using one of the documented methods from the pytz documentation:
src_dt = src_tz.localize(dt)
Change
src_dt = dt.replace(tzinfo=src_tz)
to
src_dt = src_tz.localize(dt)
Using localize
adjusts for Daylight Savings Time, while replace
does not.
See the section entitled "Localized times and date arithmetic" in the docs.