2013-11-25 2 views
27

Я пытаюсь преобразовать ISO в datetime используя код ниже:ISO на объект даты и времени: «Z» плохая директива

dt = datetime.datetime.strptime("2013-07-23T15:10:59.342107+01:00", 
           "%Y-%m-%dT%H:%M:%S.%f%z") 

и я получаю ошибку ниже:

'z' is a bad directive in format '%Y-%m-%dT%H:%M:%S.%f%z' 

Каков наилучший способ преобразования строки ISO выше формата в объект datetime? Я использую Python версии 2.7.6.

+2

связанный: [Преобразование временных меток со смещением в datetime obj с использованием strptime] (http://stackoverflow.com/q/12281975/4279) – jfs

ответ

21

Добро пожаловать в Python datetime! Работа с датами и временем обязательно сложна, и Python не поставляется полностью с батареями, включенными в этот случай. Вы не можете использовать %z в strptime, потому что у Python нет классов для представления часовых поясов (вы должны реализовать свои собственные или, еще лучше, включить некоторые другие библиотеки).

Вы хотите использовать pytz и python-dateutil. Для получения более подробной информации смотрите здесь:

Python strptime() and timezones?

+9

Мой бог-питон похож на фазу луны - на этой неделе мы это сделаем таким образом, на следующей неделе кто заботится! –

+0

Должен сказать, что отсутствие '% z' довольно неутешительно ... –

14

проблемы с питоном 2,7

У меня был аналогичной проблемой синтаксических фиксации даты с выходом git log --date=iso8601, который на самом деле не является ISO8601 формата (следовательно, добавление --date=iso8601-strict в более поздней версии).

>>> import datetime, sys 
>>> datetime.datetime.strptime("2013-07-23T15:10:59.342107+01:00", "%Y-%m-%dT%H:%M:%S.%f%z") 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/_strptime.py", line 317, in _strptime 
    (bad_directive, format)) 
ValueError: 'z' is a bad directive in format '%Y-%m-%dT%H:%M:%S.%f%z' 
>>> sys.version 
'2.7.10 (default, Feb 7 2017, 00:08:15) \n[GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.34)]' 

проблема с Python 3:

Если питон 2 не поддерживает %z из нижележащего strptime() реализации, то возможный способ решить проблему заключается в миграции на Python 3. Но это не так работа для меня:

>>> import datetime, sys 
>>> datetime.datetime.strptime("2013-07-23T15:10:59.342107+01:00", "%Y-%m-%dT%H:%M:%S.%f%z") 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/_strptime.py", line 565, in _strptime_datetime 
    tt, fraction = _strptime(data_string, format) 
    File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/_strptime.py", line 362, in _strptime 
    (data_string, format)) 
ValueError: time data '2013-07-23T15:10:59.342107+01:00' does not match format '%Y-%m-%dT%H:%M:%S.%f%z' 
>>> sys.version 
'3.6.3 (v3.6.3:2c5fed86e0, Oct 3 2017, 00:32:08) \n[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)]' 

проблема в том, что не является строго ISO8601 (обратите внимание, как там было в информации часового пояса :).

>>> datetime.datetime.strptime("2013-07-23T15:10:59.342107+0100", "%Y-%m-%dT%H:%M:%S.%f%z") 
datetime.datetime(2013, 7, 23, 15, 10, 59, 342107, tzinfo=datetime.timezone(datetime.timedelta(0, 3600))) 

решение с Джанго & pytz:

Поскольку я использую django я могу использовать утилиты там.

https://github.com/django/django/blob/master/django/utils/dateparse.py

>>> from django.utils.dateparse import parse_datetime 
>>> parse_datetime('2013-07-23T15:10:59.342107+01:00') 
datetime.datetime(2013, 7, 23, 15, 10, 59, 342107, tzinfo=+0100) 

Вместо strptime вы можете использовать свои собственные регулярные выражения.

Пожалуйста, обратите внимание, что django использует pytz под капотом для таких вещей, как Singleton utc.

раствор без Джанго & pytz:

Если вы хотите быстро и грязный раствор, вы можете использовать что-то похожее на django без всех требований.

https://gist.github.com/dnozay/3cd554a818ed768bff804bc04484905d

>>> from datetime_z import parse_datetime 
>>> parse_datetime("2013-07-23T15:10:59.342107+01:00") 
datetime.datetime(2013, 7, 23, 15, 10, 59, 342107, tzinfo=+0100) 

Обратите внимание: YMMV, нет никакой поддержки.

+1

Это действительно здорово! Не требуется сторонний пакет или собственный код парсера! Я думаю, что многие используют Django. –

+0

Это должен быть правильный ответ, если кто-то использует Django! –

+0

У вас есть решение для этого вопроса без Django? –