Objeto ISO a datetime: ‘z’ es una mala directiva

Estoy tratando de convertir ISO a datetime y datetime usando el siguiente código:

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

y obtengo el siguiente error:

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

¿Cuál es la mejor manera de convertir una cadena ISO de encima del formato a un objeto datetime ? Estoy usando Python versión 2.7.6.

    Bienvenido a Python datetime! Tratar con las fechas y los tiempos es necesariamente complejo, y Python no cuenta con baterías incluidas en este caso. No puede usar %z en strptime porque Python no tiene clases para representar las zonas horarias (se supone que debe implementar las suyas, o mejor aún incluir algunas otras bibliotecas).

    Desea usar pytz y python-dateutil . Para más detalles ver aquí:

    Python strptime () y zonas horarias?

    problema con Python 2.7

    He tenido un problema similar al analizar las fechas de confirmación de la salida de git log --date=iso8601 que en realidad no es el formato ISO8601 (de ahí la adición de --date=iso8601-strict en una versión posterior).

     >>> 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 "", line 1, in  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)]' 

    problema con python 3:

    Si python 2 no es compatible con %z debido a la strptime() subyacente de strptime() , entonces una posible forma de solucionar el problema es migrar a python 3. Pero no funcionó para mí:

     >>> 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 "", line 1, in  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)]' 

    El problema es porque no es estrictamente ISO8601 (tenga en cuenta cómo había una : en la información de la zona horaria).

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

    solución con django y pytz:

    Como uso django , puedo aprovechar las utilidades allí.

    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) 

    En lugar de strptime puedes usar tu propia expresión regular.

    Tenga en cuenta que django usa pytz debajo del capó para cosas como utc singleton.

    solución sin django y pytz:

    Si quieres una solución rápida y sucia, puedes usar algo similar a django sin todos los requisitos.

    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) 

    Tenga en cuenta: YMMV, no hay soporte.