converting from local to utc timezone

2019-03-21 11:22发布

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, i get back 18:00:00. But when i run the same data through online converters, i get 17:00:00.

What am i doing wrong here? Any help would be greatly appreciated.

import pytz, datetime

def convert_to_utc(time, tz):
    now_dt = datetime.datetime.utcnow()
    #get a date object
    date_dt = now_dt.date()
    #combine the current date object with our given time object
    dt = datetime.datetime.combine(date_dt, time)
    #get an timezone object for the source timezone
    src_tz = pytz.timezone(str(tz))
    #stamp the source datetime object with the src timezone 
    src_dt = dt.replace(tzinfo=src_tz)
    #get the offset from utc to given timezone
    offset = str(int(src_dt.strftime("%z"))).rstrip('0')
    #convert the source datetime object to
    utc_dt = src_dt.astimezone(pytz.utc)
    #return the converted time and the offset in integer format
    return (utc_dt.time(), int(offset))

time = datetime.datetime.strptime('12:00:00', "%H:%M:%S").time()
(TIME, offset) = convert_to_utc(time, 'America/Chicago')
print TIME.strftime("%H:%M:%S")

**EDIT**

Here's the updated(and functional) code in case anyone else needs help converting to/from UTC.

Thanks everyone for your help!

import pytz, datetime

def convert_to_utc(time, tz): #this returns the offset in int form as well
    now_dt = datetime.datetime.utcnow()
    #get a date object
    date_dt = now_dt.date()
    #combine the current date object with our given time object
    dt = datetime.datetime.combine(date_dt, time)
    #get an timezone object for the source timezone
    src_tz = pytz.timezone(str(tz))
    #stamp the source datetime object with the src timezone 
    src_dt = src_tz.localize(dt)
    #get the offset from utc to given timezone
    offset = str(int(src_dt.strftime("%z"))).rstrip('0')
    #convert the source datetime object to
    utc_dt = src_dt.astimezone(pytz.utc)
    #return the converted time and the offset in integer format
    return (utc_dt.time(), int(offset))

def convert_from_utc(time, tz):
    now_dt = datetime.datetime.now()
    date = now_dt.date()
    dt = datetime.datetime.combine(date, time)
    dest = pytz.timezone(str(tz))
    dt = dt.replace(tzinfo=pytz.utc)
    dest_dt = dt.astimezone(dest)
    return dest_dt.time()

time = datetime.datetime.strptime('12:00:00', "%H:%M:%S").time()
(TIME, offset) = convert_to_utc(time, 'America/Chicago')
print TIME.strftime("%H:%M:%S")

utc_time = datetime.datetime.strptime('17:00:00', "%H:%M:%S").time()
TIME = convert_from_utc(utc_time, 'America/Chicago')
print TIME.strftime("%H:%M:%S")

3条回答
小情绪 Triste *
2楼-- · 2019-03-21 11:49

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)
查看更多
老娘就宠你
3楼-- · 2019-03-21 12:08

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.

查看更多
老娘就宠你
4楼-- · 2019-03-21 12:14

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()

Example:

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.

查看更多
登录 后发表回答