2013-11-25 75 views
27

Próbuję przekonwertować ISO do datetime stosując poniższy kod:ISO do obiektu datetime: 'z' jest zły dyrektywa

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

i Dostaję błąd poniżej:

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

Jaki jest najlepszy sposób konwersji ciągu znaków ISO powyżej formatu na obiekt datetime? Używam wersji 2.7.6 w Pythonie.

+2

powiązane: [Konwertuj znaczniki czasu z offsetem do datetime obj używając strptime] (http://stackoverflow.com/q/12281975/4279) – jfs

Odpowiedz

21

Witamy w Pythonie datetime! Radzenie sobie z datami i czasami jest z konieczności skomplikowane, a Python nie jest w pełni wyposażony w baterie w tym przypadku. Nie można używać %z w strptime, ponieważ w Pythonie nie ma klas reprezentujących strefy czasowe (należy zaimplementować własne lub jeszcze lepiej włączyć inne biblioteki).

Chcesz użyć pytz i python-dateutil. Więcej szczegółów można znaleźć tutaj:

Python strptime() and timezones?

+9

Mój python bożka jest jak faza księżyca - w tym tygodniu zrobimy to w ten sposób, w przyszłym tygodniu, kogo to obchodzi! –

+0

Muszę powiedzieć, że brak '% z' jest całkiem rozczarowujący ... –

14

problem z Pythona 2.7

miałem podobny problem parsowania popełnić dat z wyjścia git log --date=iso8601 który faktycznie nie jest formatem ISO8601 (stąd dodanie --date=iso8601-strict w późniejszej wersji).

>>> 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)]' 

problem z python 3:

Jeśli python 2 nie obsługuje %z powodu leżącej strptime() realizacji, wówczas możliwy sposób, aby rozwiązać swój problem polega na migracji do Pythona 3. Ale to nie pracować dla mnie:

>>> 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)]' 

problemem jest to, ponieważ nie jest ściśle ISO8601 (zauważ, jak było : w informacji czasowej).

>>> 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))) 

rozwiązanie z Django & pytz:

Ponieważ używam django mogę wykorzystać narzędzi tam.

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) 

Zamiast strptime można użyć własnego wyrażenia regularnego.

Należy pamiętać, że django używa pytz pod maską do takich rzeczy jak singleton utc.

rozwiązanie bez django & pytz:

Jeśli chcesz szybki i brudny roztwór, można użyć coś podobnego do django bez wszystkich wymagań.

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) 

Uwaga: YMMV, nie ma wsparcia.

+1

To jest naprawdę świetne! Nie jest wymagany pakiet stron trzecich ani własny kod parsera! Myślę, że wiele osób używa Django. –

+0

To powinna być poprawna odpowiedź, biorąc pod uwagę, że ktoś używa Django! –

+0

Czy masz rozwiązanie tego pytania bez Django? –