Python - от локального времени DST до UTC

У конкретного банка есть ветки во всех крупных городах мира. Все они открыты в 10:00 по местному времени. Если в часовом поясе, который использует DST, то, конечно, время локального открытия также следует за временем, скорректированным на DST. Итак, как мне перейти с локального времени на время utc.

Мне нужна функция to_utc(localdt, tz) следующим образом:

Аргументы:

  • localdt: localtime, как наивный объект datetime, DST-скорректированный
  • tz: часовой пояс в TZ-формате, например. 'Europe/Berlin

Возврат:

  • объект datetime, в формате UTC, с учетом часовых поясов

ИЗМЕНИТЬ:

Самая большая проблема заключается в том, чтобы определить, находится ли местное время в периоде с DST, что также означает, что он настроен на DST.

Для "Европы/Берлина", где летом летает +1 DST:

  • 1 января 10:00 = > 1 января 9:00 UTC
  • 1 июля 10:00 = > 1 июля 8:00 UTC

Для "Африки/Лагоса", у которого нет ДСТ:

  • 1 января 10:00 = > 1 января 9:00 UTC
  • 1 июля 10:00 = > 1 июля 9:00 UTC

Ответ 1

Используя pytz и, в частности, метод локализации:

import pytz
import datetime as dt

def to_utc(localdt,tz):
    timezone=pytz.timezone(tz)
    utc=pytz.utc
    return timezone.localize(localdt).astimezone(utc)

if __name__=='__main__':
    for tz in ('Europe/Berlin','Africa/Lagos'):
        for date in (dt.datetime(2011,1,1,10,0,0),
                 dt.datetime(2011,7,1,10,0,0),
                 ):
            print('{tz:15} {l} --> {u}'.format(
                tz=tz,
                l=date.strftime('%b %d %H:%M'),
                u=to_utc(date,tz).strftime('%b %d %H:%M %Z')))

дает

Europe/Berlin   Jan 01 10:00 --> Jan 01 09:00 UTC
Europe/Berlin   Jul 01 10:00 --> Jul 01 08:00 UTC
Africa/Lagos    Jan 01 10:00 --> Jan 01 09:00 UTC
Africa/Lagos    Jul 01 10:00 --> Jul 01 09:00 UTC

Ответ 2

from datetime import datetime, tzinfo, timedelta

class GMT1(tzinfo):
    def utcoffset(self, dt):
        return timedelta(hours=1)
    def dst(self, dt):
        return timedelta(0)
    def tzname(self,dt):
        return "Europe/Prague"
year, month, day = 2011, 7, 23
dt = datetime(year, month, day, 10)

class UTC(tzinfo):
    def utcoffset(self, dt):
        return timedelta(0)
    def dst(self, dt):
        return timedelta(0)
    def tzname(self,dt):
        return "UTC"

def utc(localt, tz):
    return localt.replace(tzinfo=tz).astimezone(UTC())

print utc(dt, GMT1())

Новая версия. Это делает то, что вы хотите - принимает наивное datetime и часовой пояс и возвращает дату и время UTC.