2016-04-01 10 views
3

Предположим, что я получаю произвольный объект datetime в запросе, вроде этого, который может исходить из любого возможного часового пояса - я не знаю, какой из них. Ради примера, делать вид, что исходит от восточного побережьяКак конвертировать datetime из одного произвольного часового пояса в другой произвольный часовой пояс

import pytz 
from colander import iso8601 
... 
    ests1 = iso8601.parse_date('2016-04-01T00:00:00.0000-04:00') 

притвориться ests1 является объектом, который приходит в

Использование pytz, я могу узнать немного о его часовой пояс

etz = ests1.timetz() # 00:00:00-04:00 
    etzi = ests1.tzinfo # <FixedOffset '-04:00' datetime.timedelta(-1, 72000)> 
    etzn = ests1.tzname() # '-04:00' # EST 
    edst = ests1.dst() # '0:00:00' 

Обратите внимание, что независимо от того, какая дата ests1 есть - dst() всегда возвращает одинаковое значение

Я хотел бы сделать примерно следующее:

psts1 = pytz.timezone(etzn 
        ).localize(dtime.datetime.fromtimestamp(ests1) 
        ).astimezone(pytz.timezone('US/Pacific')) 

но это только приводит к

UnknownTimeZoneError: '-04:00' 

Я также попытался это:

def convert_dt_to_pstz(dt): 
    pstoffset = -25200 # -7 * 60 * 60 - but what about DST? how do we tell which offset to use? -8 or -7 
    return dt.astimezone(tzoffset(None,pstoffset)) # convert to PST 

Но проблема в том, что я не знаю, как сказать, если потребности даты для корректировки на летнее время.

Я также попытался это:

utc_date = ests1.astimezone(pytz.utc) # 2016-04-01T04:00:00+00:00 
    ptz = pytz.timezone('US/Pacific') 
    new_date = utc_date.replace(tzinfo=ptz) # 2016-04-01T04:00:00-07:53 

Но посмотрите на странный результат для NEW_DATE: -07: 53 ??

Пожалуйста, обратите внимание, что я не могу использовать любую информацию, соответствующую «сейчас» или расположения сервера, как это может быть в любом месте

+3

Обратите внимание, что чистое цифровое смещение не дает вам информации о том, действует ли летнее время. Вы должны знать больше информации о том, как было создано время, чтобы вывести, что '-04: 00' из США/восточного часового пояса, а не, скажем, из Бразилии. Однако, это деталь - я думаю, ваш вопрос интересен. Одна часть ответа - «конвертировать в UTC из исходного часового пояса; конвертировать в целевой часовой пояс из UTC '. Есть проблемы с тем, как делать эти преобразования точно. –

+0

из формата iso8601, который вы не можете сказать, он скажет -0400 для EDT и -0500 для EST, но -0400 также может быть AMT – scope

+0

@scope: Ну, есть способы определить Летнее время - но это сложный и мне интересно, есть ли что-то, что уже построено, что сделает эту работу.Я еще не нашел его, хотя – slashdottir

ответ

3

для преобразования часового пояса-Aware datetime объекта в другой часовой пояс, use datetime.astimezone() method:

pacific_time = ests1.astimezone(pytz.timezone('US/Pacific')) 

В общем, pytz docs рекомендуют называть pytz.timezone('US/Pacific').normalize() на результате, но вам не нужен его здесь, потому что ests1 часового пояса компенсировали фиксированные МЫ.

+0

, который действительно работает, спасибо – slashdottir

0

Я думаю, что я получил это право на этот раз:

from datetime import datetime as dtime 
import pytz 
from colander import iso8601 

ests1 = iso8601.parse_date('2016-04-01T00:00:00.0000-04:00') 
epoch = dtime(1970, 1, 1, tzinfo=pytz.UTC)   # 1970-01-01T00:00:00+00:00 
ept = (ests1 - epoch).total_seconds()    # 1459483200.0 

utc_date = dtime.fromtimestamp(ept, tz=pytz.UTC) # 2016-04-01T04:00:00+00:00 
ptz = pytz.timezone('US/Pacific') 
pst_date = dtime.fromtimestamp(ept, tz=ptz)   # 2016-03-31T21:00:00-07:00 

ests2 = iso8601.parse_date('2016-02-01T00:00:00.0000-04:00') 
ept2 = (ests2 - epoch).total_seconds()    # 1454299200.00 

utc_date2 = dtime.fromtimestamp(ept2, tz=pytz.UTC) # 2016-02-01T04:00:00+00:00 
pst_date2 = dtime.fromtimestamp(ept2, tz=ptz)  # 2016-01-31T20:00:00-08:00 

так, это, кажется, так просто, как

def convert_to_tz(dt,tz_new): 
    seconds = (dt - epoch).total_seconds() 
    return dtime.fromtimestamp(seconds, tz=tz_new) 

 Смежные вопросы

  • Нет связанных вопросов^_^