J'essaie de convertir ISO en datetime
en utilisant le code ci-dessous:
dt = datetime.datetime.strptime("2013-07-23T15:10:59.342107+01:00",
"%Y-%m-%dT%H:%M:%S.%f%z")
et j'obtiens l'erreur ci-dessous:
'z' is a bad directive in format '%Y-%m-%dT%H:%M:%S.%f%z'
Quelle est la meilleure façon de convertir une chaîne ISO au-dessus du format en un objet datetime
? J'utilise Python version 2.7.6.
Bienvenue dans Python datetime! La gestion des dates et des heures est nécessairement complexe, et Python ne vient pas entièrement avec les piles incluses dans ce cas. Vous ne pouvez pas utilisation %z
dans strptime
parce que Python n'a pas de classes pour représenter les fuseaux horaires (vous êtes censé implémenter les vôtres, ou mieux encore inclure d'autres bibliothèques).
Vous souhaitez utiliser pytz
et python-dateutil
. Pour plus de détails, voir ici:
J'ai rencontré un problème similaire lors de l'analyse des dates de validation à partir de la sortie de git log --date=iso8601
Qui n'est pas le format ISO8601 (d'où l'ajout de --date=iso8601-strict
Dans une version ultérieure).
>>> 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)]'
Si python 2 ne prend pas en charge %z
En raison de l'implémentation sous-jacente de strptime()
, alors un moyen possible de résoudre votre problème est de migrer vers python 3. Mais cela n'a pas fonctionné pour moi:
>>> 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)]'
Le problème est parce qu'il n'est pas strictement ISO8601 (notez comment il y avait un :
Dans les informations de fuseau horaire).
>>> 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)))
Puisque j'utilise Django
, je peux tirer parti des utilitaires là-bas.
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)
Au lieu de strptime
, vous pouvez utiliser votre propre expression régulière.
Veuillez noter que Django utilise pytz
sous le capot pour des choses comme le singleton utc
.
Si vous voulez une solution rapide et sale, vous pouvez utiliser quelque chose de similaire à Django
sans toutes les exigences.
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)
Veuillez noter: YMMV, il n'y a pas de support.