Python strptime () и часовые пояса? - PullRequest
136 голосов
/ 22 июля 2010

У меня есть дамп-файл CSV из резервной копии Blackberry IPD, созданный с использованием IPDDump. Строки даты / времени здесь выглядят примерно так (где EST - австралийский часовой пояс):

Tue Jun 22 07:46:22 EST 2010

Мне нужно иметь возможность разобрать эту дату в Python. Сначала я попытался использовать функцию strptime() из datettime.

>>> datetime.datetime.strptime('Tue Jun 22 12:10:20 2010 EST', '%a %b %d %H:%M:%S %Y %Z')

Однако по какой-то причине возвращаемый объект datetime, похоже, не связан с tzinfo.

Я прочитал на этой странице , что, по-видимому, datetime.strptime молча отбрасывает tzinfo, однако я проверил документацию и не могу найти ничего подобного, задокументированного здесь .

Мне удалось проанализировать дату с помощью сторонней библиотеки Python, dateutil , однако мне все еще интересно, как я неправильно использовал встроенный strptime()? Есть ли способ заставить strptime() хорошо играть с часовыми поясами?

Ответы [ 3 ]

323 голосов
/ 15 декабря 2011

Я рекомендую использовать python-dateutil . Его синтаксический анализатор смог проанализировать каждый формат даты, который я выбрасывал.

>>> from dateutil import parser
>>> parser.parse("Tue Jun 22 07:46:22 EST 2010")
datetime.datetime(2010, 6, 22, 7, 46, 22, tzinfo=tzlocal())
>>> parser.parse("Fri, 11 Nov 2011 03:18:09 -0400")
datetime.datetime(2011, 11, 11, 3, 18, 9, tzinfo=tzoffset(None, -14400))
>>> parser.parse("Sun")
datetime.datetime(2011, 12, 18, 0, 0)
>>> parser.parse("10-11-08")
datetime.datetime(2008, 10, 11, 0, 0)

и так далее. Не занимайтесь ерундой в формате strptime(), просто добавьте дату, и она все сделает правильно.

Обновление : Упс. Я пропустил в вашем первоначальном вопросе, который вы упомянули, что вы использовали dateutil, извините за это. Но я надеюсь, что этот ответ все еще полезен для других людей, которые сталкиваются с этим вопросом, когда у них есть вопросы разбора даты и они видят полезность этого модуля.

43 голосов
/ 22 июля 2010

Документация модуля datetime гласит:

Возвращает дату и время, соответствующие строке date_string, проанализированные в соответствии с форматом.Это эквивалентно datetime(*(time.strptime(date_string, format)[0:6])).

Видите, что [0:6]?Это дает вам (year, month, day, hour, minute, second).Ничего больше.Никаких упоминаний о часовых поясах.

Интересно, что [Win XP SP2, Python 2.6, 2.7] передача вашего примера в time.strptime не работает, но если вы удалите "% Z" и "EST", то этоработает.Также работает «UTC» или «GMT» вместо «EST».«PST» и «MEZ» не работают.Недоумение.

Стоит отметить, что это обновление было обновлено с версии 3.2, и в той же документации теперь также говорится следующее:

Когда директива% z предоставляется strptime ()метод, будет создан осведомленный объект datetime.Для tzinfo результата будет задан экземпляр часового пояса.

Обратите внимание, что это не работает с% Z, поэтому случай важен.Смотрите следующий пример:

In [1]: from datetime import datetime

In [2]: start_time = datetime.strptime('2018-04-18-17-04-30-AEST','%Y-%m-%d-%H-%M-%S-%Z')

In [3]: print("TZ NAME: {tz}".format(tz=start_time.tzname()))
TZ NAME: None

In [4]: start_time = datetime.strptime('2018-04-18-17-04-30-+1000','%Y-%m-%d-%H-%M-%S-%z')

In [5]: print("TZ NAME: {tz}".format(tz=start_time.tzname()))
TZ NAME: UTC+10:00
9 голосов
/ 04 декабря 2015

Ваша строка времени похожа на формат времени в rfc 2822 (формат даты в электронной почте, заголовки http) .Вы можете проанализировать его, используя только stdlib:

>>> from email.utils import parsedate_tz
>>> parsedate_tz('Tue Jun 22 07:46:22 EST 2010')
(2010, 6, 22, 7, 46, 22, 0, 1, -1, -18000)

См. Решения, которые предоставляют объекты даты-времени с учетом часового пояса для различных версий Python: анализ даты с часовым поясом из электронного письма .

В этом формате EST семантически эквивалентен -0500.Хотя, в общем, сокращение часового пояса недостаточно, чтобы однозначно идентифицировать часовой пояс .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...