Правильное преобразование между tz незнающим временем, UTC и работой с часовыми поясами в python - PullRequest
0 голосов
/ 27 сентября 2011

У меня есть строка в форме '20111014T090000' со связанным идентификатором часового пояса (TZID = America / Los_Angeles), и я хочу преобразовать это время в UTC в секундах с соответствующим смещением.

Проблема в том, что мое время вывода отключено на 1 час (это в PST, когда должно быть PDT), и я использую pytz, чтобы помочь с timezo

import pytz

def convert_to_utc(date_time)
    # date_time set to '2011-10-14 09:00:00' and is initially unaware of timezone information

    timezone_id = 'America/Los_Angeles'
    tz = pytz.timezone(timezone_id);

    # attach the timezone
    date_time = date_time.replace(tzinfo=tz);

    print("replaced: %s" % date_time);                                                                          
    # this makes date_time to be: 2011-10-14 09:00:00-08:00
    # even though the offset should be -7 at the present time

    print("tzname: %s" % date_time.tzname());
    # tzname reports PST when it should be PDT

    print("timetz: %s" % date_time.timetz());
    # timetz: 09:00:00-08:00 - expecting offset -7

    date_time_ms = int(time.mktime(date_time.utctimetuple())); 
    # returns '1318611600' which is 
    # GMT: Fri, 14 Oct 2011 17:00:00 GMT
    # Local: Fri Oct 14 2011 10:00:00 GMT-7

    # when expecting: '1318608000' seconds, which is
    # GMT: Fri, 14 Oct 2011 16:00:00 GMT
    # Local: Fri Oct 14 2011 9:00:00 GMT-7 -- expected value

Как получить правильное смещение на основе идентификатора часового пояса?

Ответы [ 4 ]

3 голосов
/ 27 сентября 2011

Следующий фрагмент кода будет делать то, что вы хотите

def convert(dte, fromZone, toZone):
    fromZone, toZone = pytz.timezone(fromZone), pytz.timezone(toZone)
    return fromZone.localize(dte, is_dst=True).astimezone(toZone)

Важнейшей частью здесь является передача is_dst методу локализации.

0 голосов
/ 27 марта 2014

Чтобы преобразовать данную строку в наивный объект datetime:

>>> from datetime import datetime
>>> naive_dt = datetime.strptime('20111014T090000', '%Y%m%dT%H%M%S')
>>> naive_dt
datetime.datetime(2011, 10, 14, 9, 0)

Чтобы прикрепить часовой пояс (сделать его осведомленным объектом даты и времени):

>>> import pytz
>>> tz = pytz.timezone('America/Los_Angeles')
>>> local_dt = tz.localize(naive_dt, is_dst=None)
>>> print(local_dt.strftime("%Y-%m-%d %H:%M:%S %Z%z"))
2011-10-14 09:00:00 PDT-0700

Примечание: is_dst=None используется для создания исключения для несуществующего или неоднозначного локального времени.

Чтобы получить метку времени POSIX от осведомленного объекта datetime:

>>> (local_dt - datetime(1970, 1, 1, tzinfo=pytz.utc)).total_seconds()
1318608000.0

Основные вопросы в вашем вопросе:

  1. Вы заменяете атрибут tzinfo, вместо него следует использовать tz.localize
  2. mktime() работает с местным временем (часовой пояс вашего компьютера), а не с UTC.
0 голосов
/ 10 октября 2013

Если (временно) разрешено изменение глобального часового пояса в вашей программе, вы также можете сделать это:

os.environ['TZ'] = 'America/Los_Angeles'
t = [2011, 10, 14, 9, 0, 0, 0, 0, -1]
return time.mktime(time.struct_time(t))

Возвращается ожидаемое 1318608000.0.

0 голосов
/ 23 июня 2013

simple-date было написано для преобразования, подобного этому тривиальному (для этого вам нужна версия 0.2.1 или более поздняя):

>>> from simpledate import *
>>> SimpleDate('20111014T090000', tz='America/Los_Angeles').timestamp
1318608000.0
...