Разобрать аббревиатуру часового пояса до UTC

Как я могу преобразовать строку даты и времени в форме Feb 25 2010, 16:19:20 CET в эпоху unix?

В настоящее время мой лучший подход - использовать time.strptime():

def to_unixepoch(s):
    # ignore the time zone in strptime
    a = s.split()
    b = time.strptime(" ".join(a[:-1]) + " UTC", "%b %d %Y, %H:%M:%S %Z")
    # this puts the time_tuple(UTC+TZ) to unixepoch(UTC+TZ+LOCALTIME)
    c = int(time.mktime(b))
    # UTC+TZ
    c -= time.timezone
    # UTC
    c -= {"CET": 3600, "CEST": 2 * 3600}[a[-1]]
    return c

Из других вопросов я вижу, что можно было бы использовать calendar.timegm() и pytz среди других, чтобы упростить это, но они не обрабатывают сокращенные часовые пояса.

Мне нужно решение, которое требует минимального количества лишних библиотек, я предпочитаю придерживаться стандартной библиотеки, насколько это возможно.


person Matt Joiner    schedule 25.02.2010    source источник
comment
Да, у меня тоже получился собственный поиск аббревиатуры произвольного часового пояса. Я не думаю, что общий случай разрешим, поскольку существует несколько часовых поясов с одной и той же аббревиатурой во всем мире.   -  person bobince    schedule 25.02.2010
comment
@bobince: хорошо, приятно знать, что я кое-что не упустил. я нашел эту замечательную ссылку, которая заставляет меня чувствовать себя в большей безопасности в отношении описанного выше метода: timeanddate.com/ библиотека / сокращения / часовые пояса   -  person Matt Joiner    schedule 26.02.2010


Ответы (1)


Стандартная библиотека Python не поддерживает часовые пояса. Вам следует использовать python-dateutil. Он предоставляет полезные расширения к стандартному модулю datetime, включая реализацию часовых поясов и синтаксический анализатор.

Вы можете преобразовать datetime объекты с учетом часового пояса в формат UTC с помощью .astimezone(dateutil.tz.tzutc()). Для текущего времени в качестве объекта datetime, учитывающего часовой пояс, вы можете использовать datetime.datetime.utcnow().replace(tzinfo=dateutil.tz.tzutc()).

import dateutil.tz

cet = dateutil.tz.gettz('CET')

cesttime = datetime.datetime(2010, 4, 1, 12, 57, tzinfo=cet)
cesttime.isoformat()
'2010-04-01T12:57:00+02:00'

cettime = datetime.datetime(2010, 1, 1, 12, 57, tzinfo=cet)
cettime.isoformat() 
'2010-01-01T12:57:00+01:00'

# does not automatically parse the time zone portion
dateutil.parser.parse('Feb 25 2010, 16:19:20 CET')\
    .replace(tzinfo=dateutil.tz.gettz('CET'))

К сожалению, этот метод будет неправильным во время повторяющегося часа перехода на летнее время.

person joeforker    schedule 25.02.2010
comment
чего ждать? Я думал, что эпоха UNIX универсальна. 0 - полночь по Гринвичу, а будет 1 час ночи по центральноевропейскому времени. locality вступает в игру только при переходе туда и обратно к time_tuple - person Matt Joiner; 26.02.2010
comment
Вы правы, time.time () должен быть в формате UTC. - person joeforker; 26.02.2010
comment
Хорошо, спасибо за проверку, если бы я ошибался, мой мир разрушился бы :) - person Matt Joiner; 26.02.2010
comment
Я бы все равно сам проверил. Википедия говорит, что это должно быть UTC. - person joeforker; 26.02.2010