622 votes

Comment traduire une chaîne de dates ISO 8601 en un objet datetime Python ?

J'obtiens une chaîne de date dans un format tel que "2009-05-28T16:15:00" (c'est la norme ISO 8601, je crois). Il semble que l'une des options possibles soit d'analyser la chaîne en utilisant time.strptime et en passant les six premiers éléments du tuple dans le constructeur de datetime, comme :

datetime.datetime(*time.strptime("2007-03-04T21:08:12", "%Y-%m-%dT%H:%M:%S")[:6])

Je n'ai pas réussi à trouver une façon plus "propre" de le faire. En existe-t-il une ?

28 votes

Il est bon de garder à l'esprit que ce n'est pas tout à fait un duplicata du problème contre lequel il a été fermé. Le problème lié se réfère spécifiquement à RFC 3339 tandis que celui-ci fait référence aux chaînes ISO 8601. La syntaxe RFC 3339 est un sous-ensemble de la syntaxe ISO 8601 (définie dans la norme non libre ISO 8601 qui, comme la plupart des normes ISO, doit être piratée ou faire l'objet d'une énorme redevance pour être lue). La chaîne de date présentée dans cette question est une date ISO 8601, mais PAS une date RFC 3339. Les décalages UTC sont obligatoires dans les dates RFC 3339, et aucun n'est fourni ici.

938voto

Wes Winham Points 570

Je préfère utiliser le dateutil pour la gestion des fuseaux horaires et l'analyse des dates. Si vous obtenez un ISO 8601 comme une chaîne de caractères : 2010-05-08T23:41:54.000Z vous vous amuseriez à analyser cela avec strptime, surtout si vous ne savez pas d'emblée si le fuseau horaire est inclus ou non. pyiso8601 a quelques problèmes (vérifiez leur tracker) que j'ai rencontrés pendant mon utilisation et il n'a pas été mis à jour depuis quelques années. dateutil, en revanche, a été actif et a fonctionné pour moi :

from dateutil import parser
yourdate = parser.parse(datestring)

5 votes

C'est vrai, pyiso8601 a quelques problèmes très subtils que l'on peut remarquer quand ils sont déjà répandus dans tout le code. dateutil.parser est vraiment bon, mais on devrait garder un oeil sur l'application de la conscience tz manuellement si nécessaire.

5 votes

Une mise à jour de pyiso8601 début février 2014 a résolu de nombreux problèmes. Elle gère un ensemble beaucoup plus large de chaînes ISO8601 valides. Cela vaut la peine d'y jeter un autre coup d'œil.

3 votes

Je me suis arraché les cheveux avec une tonne de elif essaie d'utiliser datetime.datetime.strptime pour gérer tous mes différents formats de date. MERCI de m'avoir montré la lumière.

332voto

Bluebird75 Points 4612

Depuis Python 3.7 et l'absence de bibliothèques externes, vous pouvez utiliser la fonction fonction fromisoformat de la module datetime :

datetime.datetime.fromisoformat('2019-01-04T16:41:24+0200')

Python 2 ne prend pas en charge l'option %z Il est donc préférable d'utiliser explicitement l'heure zouloue partout si possible :

datetime.datetime.strptime("2007-03-04T21:08:12Z", "%Y-%m-%dT%H:%M:%SZ")

3 votes

Peut-être cherchiez-vous les fonctions du module datetime, au lieu des méthodes de la classe datetime.datetime.

51 votes

Vous devez cependant admettre que cela contredit l'idéologie python, étant plutôt peu évident... strptime ? Ne pouvaient-ils pas utiliser un nom significatif plutôt que de propager un vieux nom de C merdique ?....

11 votes

Notez que cela analyse un sous-ensemble de la norme ISO 8601. Si vous dites à votre client que vous pouvez analyser toutes les dates 8601, il peut vous en envoyer une sans tirets, sans deux-points, avec un chiffre de la semaine au lieu du mois, etc.

46voto

Avi Flax Points 14898

Flèche semble prometteur pour cela :

>>> import arrow
>>> arrow.get('2014-11-13T14:53:18.694072+00:00').datetime
datetime.datetime(2014, 11, 13, 14, 53, 18, 694072, tzinfo=tzoffset(None, 0))

Arrow est une bibliothèque Python qui offre une manière intelligente de créer, manipuler, formater et convertir des dates et des heures. Arrow est simple, léger et fortement inspiré de moment.js y demande .

19voto

Daniel F. Points 836

Vous devez garder un œil sur les informations relatives au fuseau horaire, car vous risquez d'avoir des problèmes en comparant des dates qui ne tiennent pas compte du fuseau horaire avec d'autres qui en tiennent compte.

Il est probablement préférable de toujours les rendre conscients du tz (même si ce n'est qu'en tant qu'UTC), à moins que vous ne sachiez vraiment pourquoi il ne serait pas utile de le faire.

#-----------------------------------------------
import datetime
import pytz
import dateutil.parser
#-----------------------------------------------

utc = pytz.utc
BERLIN = pytz.timezone('Europe/Berlin')
#-----------------------------------------------

def to_iso8601(when=None, tz=BERLIN):
  if not when:
    when = datetime.datetime.now(tz)
  if not when.tzinfo:
    when = tz.localize(when)
  _when = when.strftime("%Y-%m-%dT%H:%M:%S.%f%z")
  return _when[:-8] + _when[-5:] # Remove microseconds
#-----------------------------------------------

def from_iso8601(when=None, tz=BERLIN):
  _when = dateutil.parser.parse(when)
  if not _when.tzinfo:
    _when = tz.localize(_when)
  return _when
#-----------------------------------------------

9voto

Avi Flax Points 14898

Je ne l'ai pas encore essayé, mais pyiso8601 promet de le soutenir.

4 votes

Pyiso8601 a un très La gamme limitée de formats qu'il accepte. Mieux vaut utiliser dateutil.parser --> "Actuellement, les formats suivants sont gérés : 1) 2006-01-01T00:00:00Z 2) 2006-01-01T00:00:00[+-]00:00" Avoir [+-]0000 comme information tz est tout aussi valable sous la norme ISO. IIRC sur [+-]0000, l'information tz est simplement rejetée...

1 votes

pyiso8601 a été mis à jour récemment (vers février 2014) et gère désormais les [+-]0000. Il gère aussi uniquement les dates. J'ai utilisé pyiso8601 à bon escient.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X