Ответ 1
Измените
src_dt = dt.replace(tzinfo=src_tz)
к
src_dt = src_tz.localize(dt)
Использование localize
настраивается для летнего времени, а replace
- нет.
См. Раздел "Локализованное время и арифметика дат" в документах.
Я пытаюсь создать функцию, которая принимает объект времени и преобразует его в UTC. Код ниже, кажется, выключен на один час. Когда я запускаю полдень через конвертер, я возвращаюсь в 18:00:00. Но когда я запускаю одни и те же данные через онлайн-конвертеры, я получаю 17:00:00.
Что я здесь делаю неправильно? Любая помощь будет принята с благодарностью.
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 **
Здесь обновленный (и функциональный) код в случае, если кому-то еще нужна помощь в преобразовании в/из UTC.
Спасибо всем за вашу помощь!
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")
Измените
src_dt = dt.replace(tzinfo=src_tz)
к
src_dt = src_tz.localize(dt)
Использование localize
настраивается для летнего времени, а replace
- нет.
См. Раздел "Локализованное время и арифметика дат" в документах.
Используя метод replace
в datetime, вы не позволяете настроить часовой пояс для перехода на летнее время. Попробуйте использовать один из документированных методов из документации pytz:
src_dt = src_tz.localize(dt)
Чтобы преобразовать время в заданном часовом поясе в время UTC:
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()
если is_dst
- None
, он вызывает исключение для неоднозначных локальных времен.
Чтобы преобразовать время UTC в локальное время в заданный часовой пояс:
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
В общем, желательно работать с полными объектами datetime
, чтобы избежать двусмысленности с тем, что является правильной датой, то есть передавать и возвращать объекты datetime
.