RFC 3339 en Go : 5 erreurs de parsing de dates et comment les corriger

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Parsing RFC 3339 / ISO-8601 en Go : pourquoi même les développeurs expérimentés trébuchent

\n\n

Avez-vous déjà écrit en Go quelque chose comme time.Parse("2006-01-02T15:04:05Z", input), obtenu une erreur, et eu l'impression que le langage se moquait de vous ? Familier. Le parsing des dates et heures est l'un de ces sujets où tout semble simple, mais où de nombreux pièges vous attendent en pratique.

\n\n

Sur Stack Overflow, la question "Parsing RFC-3339 / ISO-8601 date-time string in Go" a rassemblé des milliers de vues. Les gens se perdent dans les formats, oublient les nanosecondes, souffrent des fuseaux horaires et s'énervent contre le nombre « magique » 2006-01-02T15:04:05Z. Dans cet article, nous allons analyser 5 erreurs les plus fréquentes et montrer comment les éviter une fois pour toutes. C'est parti !

\n\n

Un peu de théorie : qu'est-ce que RFC 3339 et ISO 8601 ?

\n\n

Avant de plonger dans le code, clarifions rapidement les termes. ISO 8601 est une norme internationale pour la représentation de la date et de l'heure. RFC 3339 en est une version « allégée », populaire sur le web (par exemple, dans JSON, les API, les logs).

\n\n

Les chaînes RFC 3339 typiques ressemblent à ceci :

\n\n
2025-01-15T10:30:00Z\n2025-01-15T10:30:00+03:00\n2025-01-15T10:30:00.123456789Z
\n\n

En Go, la fonction utilisée pour le parsing est time.Parse(layout, value). Et c'est là que les choses deviennent intéressantes.

\n\n

Erreur n°1 : Mauvais layout (modèle) — la principale cause de maux de tête

\n\n

Go utilise une approche unique : le format n'est pas défini par des codes comme YYYY-MM-DD, mais par une date spécifique : Mon Jan 2 15:04:05 MST 2006. Il est facile à retenir : 01/02 03:04:05PM '06 -0700 (mois, jour, heure, minute, seconde, année, fuseau horaire).

\n\n

Les débutants essaient souvent d'écrire quelque chose comme :

\n\n
// ❌ Erreur !\nt, err := time.Parse("YYYY-MM-DDTHH:MM:SSZ", "2025-01-15T10:30:00Z")
\n\n

Go ne comprendra tout simplement pas ce format. Le layout correct pour RFC 3339 est time.RFC3339 :

\n\n
// ✅ Correct\nt, err := time.Parse(time.RFC3339, "2025-01-15T10:30:00Z")\nif err != nil {\n    log.Fatal(err)\n}\nfmt.Println(t) // 2025-01-15 10:30:00 +0000 UTC
\n\n

La constante time.RFC3339 est égale à la chaîne "2006-01-02T15:04:05Z07:00". Notez le Z07:00 — c'est la désignation du fuseau horaire.

\n\n

Erreur n°2 : Ignorer les nanosecondes (time.RFC3339 vs time.RFC3339Nano)

\n\n

Le time.RFC3339 standard ne prend pas en charge les nanosecondes. Si votre chaîne contient une partie fractionnaire de seconde :

\n\n
2025-01-15T10:30:00.123456789Z
\n\n

…alors le parsing avec time.RFC3339 renverra une erreur :

\n\n
// ❌ Erreur : parsing time "2025-01-15T10:30:00.123456789Z" as "2006-01-02T15:04:05Z07:00": cannot parse ".123456789Z" as "Z07:00"\nt, err := time.Parse(time.RFC3339, "2025-01-15T10:30:00.123456789Z")
\n\n

La solution est d'utiliser time.RFC3339Nano :

\n\n
// ✅ Correct\nt, err := time.Parse(time.RFC3339Nano, "2025-01-15T10:30:00.123456789Z")\nif err != nil {\n    log.Fatal(err)\n}\nfmt.Println(t) // 2025-01-15 10:30:00.123456789 +0000 UTC
\n\n

Conseil : Si vous n'êtes pas sûr de la présence de nanosecondes, utilisez time.RFC3339Nano — il est rétrocompatible et fonctionnera dans les deux cas.

\n\n

Erreur n°3 : Fuseau horaire — Z ou +00:00 — est-ce la même chose ?

\n\n

Les chaînes 2025-01-15T10:30:00Z et 2025-01-15T10:30:00+00:00 signifient la même chose (UTC), mais Go peut les traiter différemment si le layout est mal spécifié.

\n\n
// ✅ Les deux variantes fonctionnent avec time.RFC3339\nt1, _ := time.Parse(time.RFC3339, "2025-01-15T10:30:00Z")\nt2, _ := time.Parse(time.RFC3339, "2025-01-15T10:30:00+00:00")\nfmt.Println(t1.Equal(t2)) // true
\n\n

Mais si vous écrivez votre propre layout, soyez attentif :

\n\n
    \

Blogs

Book Recommendations