Aller au contenu
Allin

Écrire une date en ISO 8601, et pourquoi c'est le seul format non ambigu

Publié le 13/08/2026 · 17 min de lecture · Outils texte & langage

Daniel Okonkwo

Daniel OkonkwoDéveloppeur front-end et rédacteur Tech chez Allin

Performance web · Formats de fichiers

Vérifié à partir de 4 sources

Voir le profil
En bref

Écris l'année d'abord, puis le mois, puis le jour, chacun complété par des zéros : 2026-02-01. L'ordre est toute l'astuce. Comme les champs vont de la plus grande unité à la plus petite et que chacun a une largeur fixe, comparer deux chaînes caractère par caractère donne la même réponse que comparer les deux instants — d'où le fait que trier un dossier de fichiers nommés ainsi les met en ordre chronologique sans aucune logique de date. Une heure se rattache à la date par un T majuscule, et un décalage par rapport à UTC s'ajoute : 2026-02-01T09:30:00+01:00, ou Z quand le décalage est nul. Une date-heure sans décalage est une date locale dont le sens dépend du lieu de lecture, exactement l'ambiguïté que le format existe pour supprimer : ajoute donc le décalage, sauf si tu veux vraiment parler d'une horloge murale. L'outil a été passé sur ces cas : il conserve un instant sous forme de sept entiers et convertit par arithmétique entière plutôt qu'avec un objet Date, si bien que 2026-08-13T00:30:00+02:00 revient en 2026-08-12T22:30:00Z, un jour plus tôt et correct, avec un horodatage Unix de 1786573800 identique à Date.UTC. Son bouton « Maintenant » lit l'horloge en UTC : juste après minuit à Paris, il préremplit donc la date de la veille — surprenant, pas faux. Deux mises en garde. Le tri textuel n'égale le tri temporel que si toutes les chaînes portent le même décalage ; mélange Z et +02:00 et l'ordre devient faux en silence. Et l'ISO 8601 est plus large que la RFC 3339, qui est ce qu'exigent réellement la plupart des API : une date seule, une date de semaine, une chaîne en format basique et une heure 24 sont toutes de l'ISO 8601 valide, et aucune n'est de la RFC 3339 valide.

01/02/2026, c'est le 1er février dans la plus grande partie de l'Europe et le 2 janvier aux États-Unis, et rien dans la chaîne ne dit lequel. ISO 8601 règle cela, se trie comme du texte, et cesse d'être accepté en quatre points précis que la RFC 3339 refuse.

01/02/2026, et les six langues dans lesquelles ce site est écrit

Un lecteur à Paris, Madrid, Lisbonne, Berlin ou Rome lit 01/02/2026 comme le 1er février. Un lecteur aux États-Unis lit les mêmes huit chiffres comme le 2 janvier. Rien dans la chaîne ne tranche : les deux lectures sont complètes, les deux sont conventionnelles, et les deux se trompent une fois sur deux dès que la chaîne a voyagé.

L'échec est silencieux, et c'est ce qui le rend coûteux. Un formulaire accepte la date, une base la stocke, un rapport l'imprime, et rien ne proteste jusqu'au douzième jour du mois, où les deux lectures cessent de produire chacune une date valide et où l'une finit par lever une erreur. Tout ce qui se trouvait entre le 1er et le 12 a été décalé en silence. Une livraison prévue le 3 avril arrive le 4 mars, une facture est datée onze mois trop tôt, et la piste d'audit enregistre les deux comme des écritures parfaitement ordinaires.

2026-02-01 n'a pas de seconde lecture. L'année vient d'abord parce que c'est la plus grande unité, le mois ensuite, le jour en dernier, et chacun est complété à une largeur fixe. Aucune locale à consulter, aucune convention de séparateur à deviner, aucun mois qui puisse passer pour un jour. C'est tout l'apport de la norme, et cela suffit.

Trier comme du texte et trier dans le temps sont la même opération

Ordonne les champs du plus grand au plus petit, complète chacun à une largeur fixe, et la comparaison lexicographique devient gratuitement une comparaison chronologique. Cinq instants ont été passés dans l'outil, triés une fois comme des chaînes et une fois par leurs horodatages Unix : les deux ordres étaient identiques. C'est cette propriété qui fait qu'un dossier de fichiers nommés 2026-02-01-notes.md, 2026-02-11-notes.md et 2026-10-02-notes.md est dans le bon ordre dans tout gestionnaire de fichiers, tout shell, toute liste de sauvegarde — sans aucune analyse de date dans la chaîne.

La propriété a une condition facile à perdre : toutes les chaînes doivent porter le même décalage. Deux instants ont été passés pour le montrer. 2026-01-05T09:00:00Z et 2026-01-05T10:00:00+02:00 se trient dans cet ordre en tant que texte, parce que le caractère 9 précède le caractère 1 suivi de 0. Leurs horodatages Unix sont 1767603600 et 1767600000 : le second s'est produit en premier. L'ordre textuel est faux et rien ne le signale. Si une colonne peut contenir des décalages mélangés, normalise tout en Z avant de trier, ou trie sur l'horodatage.

Le même raisonnement explique la convention de nommage des fichiers. Mets la date au début du nom et le dossier se trie tout seul ; mets-la à la fin et il se trie sur ce qui précède. Utilise des tirets plutôt que des barres obliques, car la barre est un séparateur de chemin sur tous les systèmes, et les deux-points — légaux dans une heure mais interdits dans un nom de fichier sous Windows — expliquent pourquoi un nom horodaté retombe généralement sur 2026-02-01T093000Z, le format basique que la norme définit aussi.

Le T, le Z, et un décalage qui n'est pas un fuseau horaire

Le T majuscule relie la date à l'heure. Il est là parce qu'une date et une heure sont deux représentations distinctes et qu'il faut bien dire où l'une finit et où l'autre commence ; une espace ferait l'affaire pour un humain, et c'est exactement ce qu'imprime une base de données, mais la norme stricte veut le T. Le Z final signifie un décalage nul — Zulu, de l'alphabet phonétique militaire — et il est interchangeable avec +00:00.

Un décalage comme +02:00 dit de combien l'horloge murale s'écarte d'UTC à cet instant, et rien de plus. Il ne nomme pas Paris : c'est aussi Le Caire, Johannesburg, Helsinki et la moitié de l'Europe au même moment, et la même horloge parisienne est à +01:00 en janvier. C'est pourquoi un rendez-vous futur doit être stocké comme identifiant de fuseau — Europe/Paris — avec l'heure locale, et non comme un décalage. Stocke 2027-03-28T10:00:00+01:00 pour une réunion et elle aura lieu à neuf heures après le changement d'heure, ce dont personne n'a convenu.

Une date-heure sans aucun décalage est une date locale, et son sens est celui que décide la machine du lecteur. C'est de l'ISO 8601 valide et c'est parfois ce que tu veux — une boutique ouvre à 09:00 dans la ville où elle se trouve — mais ce n'est pas un instant, et le traiter comme tel est la façon dont une ligne de journal venue d'un serveur étranger arrive à la mauvaise heure, et dont une date de naissance en base devient la veille pour quiconque est à l'ouest du méridien.

À la chasse au décalage d'un jour autour de minuit, sans le trouver

Le défaut le plus courant dans l'outillage de dates est une conversion qui passe par le fuseau local du navigateur et atterrit un jour à côté près de minuit. Celui-ci ne l'a pas, pour une raison structurelle : il ne touche jamais à l'heure locale. Un instant est conservé sous forme de sept entiers — année, mois, jour, heure, minute, seconde et décalage en minutes — et la conversion vers UTC décale le numéro de jour par arithmétique entière plutôt qu'en construisant un Date. Le bouton « Maintenant » lit l'horloge via getUTCFullYear et ses voisines et fixe le décalage à UTC+00:00.

Les cas limites ont été passés exprès. Paris à 00:30 le 13 août avec un décalage de +02:00 donne une forme UTC 2026-08-12T22:30:00Z et une date HTTP Wed, 12 Aug 2026 22:30:00 GMT — un jour plus tôt, ce qui est correct, puisque c'est le même instant. New York à 23:30 le 12 août avec un décalage de −04:00 va dans l'autre sens, vers 2026-08-13T03:30:00Z. Les îles Chatham à 00:10 le 1er janvier avec un décalage de +12:45 ressortent en 2025-12-31T11:25:00Z, franchissant à la fois un jour et une année. Cinq de ces cas ont été recoupés avec Date.UTC, y compris le 1969-07-20T20:17:40Z antérieur à l'epoch, dont l'horodatage de −14 182 940 correspond exactement.

La seule chose qui ressemble à un décalage d'un jour est le bouton « Maintenant », et c'est un choix délibéré qui transparaît. Comme l'horloge est lue en UTC, un lecteur parisien qui l'active à minuit et demi le 13 août voit le champ de date prérempli au 12 août et l'heure à 22:30. C'est le même moment exprimé dans le fuseau par défaut de l'outil, pas la date d'hier. Si tu veux ta propre horloge murale, saisis la date et l'heure à la main et choisis ton décalage dans la liste.

La RFC 3339 est ce que veut dire ton API, et elle est plus étroite

Quand une API dit vouloir de l'ISO 8601, elle veut presque toujours de la RFC 3339, qui se décrit elle-même comme un profil d'ISO 8601 pour usage sur Internet. Un profil est un sous-ensemble : tout ce que la RFC 3339 accepte est de l'ISO 8601, et une grande partie de l'ISO 8601 n'est pas de la RFC 3339. Sa grammaire exige une date complète, puis un T, puis une heure complète, puis un décalage — rien ne peut être omis.

Quatre différences comptent en pratique, toutes lisibles dans la grammaire de la RFC. Son heure est définie comme deux chiffres de 00 à 23 : 24:00 — fin de journée légale en ISO, désignant le même instant que minuit le lendemain — n'est donc pas de la RFC 3339. Son décalage s'écrit signe, deux chiffres, deux-points, deux chiffres : +0200 et +02 sont de l'ISO 8601 et ni l'un ni l'autre n'est de la RFC 3339. Elle n'a ni dates de semaine ni dates ordinales : 2026-W33-4 et 2026-225 lui échappent. Et une date nue comme 2026-08-13, ou une année et un mois, ou une année seule, n'est pas du tout une date-heure au sens de la RFC 3339.

Deux subtilités vont dans l'autre sens, là où la RFC 3339 est plus permissive. Elle donne à −00:00 un sens propre : l'heure UTC est connue mais le décalage local ne l'est pas, ce qui diffère volontairement de Z ou de +00:00. Et une note de la même section indique que les applications peuvent employer une espace à la place du T pour la lisibilité, ce qu'impriment précisément les bases de données. L'outil accepte une espace collée et te dit qu'il l'a vue ; il accepte aussi −00:00 et le transforme silencieusement en Z, si bien que la distinction posée par la RFC ne survit pas à un aller-retour.

Une conséquence mérite d'être signalée, parce que l'outil ne le fait pas. Son champ de sortie principal, celui étiqueté comme forme étendue date et heure, est de la RFC 3339 dès lors que l'heure est comprise entre 00 et 23 — et ne l'est pas quand l'heure vaut 24, ce que l'analyseur accepte. Colle 2026-08-13T24:00:00Z et ce champ te le renvoie tel quel, et le champ étiqueté date d'e-mail imprime une heure que la RFC 5322 n'autorise pas davantage. La ligne UTC à côté, elle, est juste : elle indique 2026-08-14T00:00:00Z. Si tu copies une valeur vers une API, copie celle-là.

Dates de semaine, dates ordinales, et les petites choses que l'outil rate

L'ISO 8601 définit deux autres formes de date, et l'outil imprime les deux. Une date de semaine nomme l'année, la semaine et le jour de la semaine, et son année n'est pas toujours l'année civile : une semaine appartient à l'année qui contient son jeudi. Passe le 1er janvier 2027 dans l'outil et il revient en 2026-W53-5 ; passe le 31 décembre 2024 et il revient en 2025-W01-2. Les deux ont été vérifiés. Une date ordinale nomme l'année et le jour qu'elle contient : le 13 août 2026 est donc 2026-225. Les deux se trient lexicographiquement aussi bien que les dates civiles — mais ne mélange jamais les trois formes dans une même colonne, car 2026-W33-4 et 2026-08-13 se trient l'une contre l'autre comme des chaînes, sans aucun rapport avec le temps.

Trois petits défauts sont apparus aux tests ; ils méritent d'être connus plutôt que redoutés. Une seconde à 60 est acceptée partout — colle 2026-08-13T00:30:60Z et l'outil la prend et calcule un horodatage Unix de 1786581060, soit 00:31:00 — alors que la norme comme la RFC n'admettent 60 que sous les règles de la seconde intercalaire. Les fractions de seconde sont lues puis jetées : 2026-08-13T00:30:00.123Z revient en 2026-08-13T00:30:00Z, sans le moindre avis que les millisecondes ont disparu. Et l'analyseur de durées rejette P0D, durée nulle pourtant légale, parce qu'il écarte toute durée dont tous les champs valent zéro.

Ce qu'il fait bien mérite la même phrase. Il refuse 2026-02-30 et 2026-08-13T25:00:00Z, refuse un 2026-8-3 non complété, et refuse net 13/08/2026 et 08/13/2026, ce qui est la bonne réponse pour un outil dont le travail est de dire ce qui est ou non de l'ISO 8601. Il lit le format basique 20260813T003000+0200, lit un t et un z minuscules, et te dit laquelle des trois formes de date il a reconnue. Les durées s'analysent correctement aussi, y compris la virgule décimale de P1,5D, qu'il normalise en P1.5D.

Chaînes que l'outil accepte ou imprime, et si chacune est de l'ISO 8601, de la RFC 3339, ou les deux
ChaîneStatutPourquoi
2026-08-13T00:30:00+02:00Les deuxDate complète, T, heure complète, décalage avec deux-points — exactement la grammaire RFC 3339
2026-08-13ISO 8601 seulementLa RFC 3339 définit une date-heure, pas une date seule
2026-W33-4T12:00:00+02:00ISO 8601 seulementLes dates de semaine sont absentes de la grammaire RFC 3339 ; l'outil la lit comme le 13 août 2026
20260813T003000+0200ISO 8601 seulementLe format basique supprime les séparateurs ; la RFC 3339 les exige
2026-08-13T24:00:00ZISO 8601 seulement — et l'outil le réimprimeLa RFC 3339 fixe l'heure de 00 à 23 ; la ligne UTC affiche correctement 2026-08-14T00:00:00Z
2026-08-13 00:30:00Z, avec une espaceRFC 3339 par une note ; l'outil l'accepte et le signaleUne note de la section 5.6 autorise une espace pour la lisibilité ; la norme stricte veut le T
2026-08-13T00:30:00-00:00RFC 3339 seulement ; l'outil le transforme en ZLa section 4.3 lui donne le sens « décalage inconnu », que la conversion efface
2026-08-13T00:30:60ZNi l'un ni l'autre, et l'outil l'accepteUne seconde à 60 est une seconde intercalaire, seulement à 23:59:60 ; l'horodatage ressort en 00:31:00
13/08/2026 et 08/13/2026Ni l'un ni l'autre ; l'outil refuse les deuxL'ambiguïté que toute la norme existe pour supprimer — refuser est la bonne réponse
Formateur de date ISO 8601Transforme une date, une heure et un décalage UTC en ISO 8601, RFC 3339, date de semaine/ordinale, RFC 2822, date HTTP et horodatages Unix.Essayer l'outil

Questions fréquentes

Faut-il écrire le décalage ou utiliser Z partout ?
Pour tout ce que tu stockes, journalises ou envoies entre machines, normalise en Z. Toutes les valeurs portent alors le même décalage : le tri textuel égale le tri temporel, les comparaisons n'exigent aucune conversion, et il n'y a rien à rater. Ne garde le décalage local que quand la lecture locale est elle-même le fait — un reçu qui doit indiquer que la transaction a eu lieu à 09:15 dans la matinée du magasin, un départ de train imprimé pour les voyageurs. Et pour un rendez-vous futur, aucun des deux ne convient : stocke l'identifiant de fuseau et l'heure locale, car le décalage qu'aura ce fuseau à cette date est une décision que personne n'a encore prise.
L'ISO 8601 et la RFC 3339, est-ce la même chose ?
Non. La RFC 3339 se présente comme un profil d'ISO 8601 pour les protocoles Internet, et un profil est un sous-ensemble. Sa grammaire n'admet que la date calendaire, exige la présence de l'heure et du décalage, limite l'heure de 00 à 23, et écrit le décalage avec deux-points et minutes obligatoires. Une date nue, une date de semaine comme 2026-W33-4, une date ordinale comme 2026-225, le format basique sans tirets, une heure 24 et un décalage écrit +0200 ou +02 sont donc tous de l'ISO 8601 valide, et aucun n'est de la RFC 3339 valide. Dans l'autre sens, la RFC 3339 donne à -00:00 un sens propre — l'heure UTC est connue mais le décalage local ne l'est pas — et autorise t et z minuscules. Quand une API demande de l'ISO 8601, envoie de la RFC 3339 et tu satisferas les deux.
Pourquoi l'outil affiche-t-il la date d'hier quand je clique sur « Maintenant » ?
Parce qu'il lit l'horloge en UTC et fixe le décalage à UTC+00:00, pas parce qu'il compte mal. Si tu es à l'est de Greenwich et qu'il est un peu plus de minuit, ton horloge murale est déjà au jour nouveau alors qu'UTC est encore à l'ancien. Un lecteur parisien qui clique sur « Maintenant » à 00:30 le 13 août voit 12 août et 22:30 remplis — le même moment, exprimé dans le fuseau par défaut de l'outil. Rien dans la conversion ne passe par le fuseau de ta machine : l'instant est conservé en entiers et décalé par arithmétique entière, et cinq cas limites, dont une date antérieure à l'epoch et un décalage de +12:45, ont correspondu exactement à Date.UTC. Si tu veux ton heure murale, saisis la date et l'heure et choisis ton décalage dans la liste.
Puis-je vraiment trier des dates en triant le texte ?
Oui, à une condition : toutes les chaînes doivent avoir la même forme et le même décalage. Cinq instants ont été triés des deux façons dans l'outil et les ordres étaient identiques. Casse la condition et cela échoue en silence : 2026-01-05T09:00:00Z se trie avant 2026-01-05T10:00:00+02:00 en texte, mais leurs horodatages sont 1767603600 et 1767600000 : celui qui arrive second s'est produit en premier. Mélanger dates civiles et dates de semaine casse tout autant, puisque 2026-W33-4 se compare à 2026-08-13 comme deux chaînes sans signification commune. Normalise en Z et en une seule forme avant de trier, et l'astuce est parfaitement sûre — c'est exactement pour cela que c'est la bonne façon de nommer des fichiers.
Pourquoi le 1er janvier 2027 s'écrit-il 2026-W53-5 ?
Parce qu'une semaine appartient entièrement à une seule année, et que la norme l'attribue à celle qui contient son jeudi. La semaine du 1er janvier 2027 a son jeudi le 31 décembre 2026 : toute la semaine est donc la semaine 53 de l'année de numérotation 2026, et le vendredi qu'elle contient est le jour 5. La même règle joue dans l'autre sens : le 31 décembre 2024 ressort en 2025-W01-2, les deux vérifiés dans l'outil. Deux conséquences pratiques. L'année de numérotation des semaines n'est pas l'année civile et ne doit jamais être accolée à un mois civil dans un titre de rapport. Et une année compte 53 semaines quand son 1er janvier est un jeudi, ou un mercredi en année bissextile — 2026 en a 53, 2027 en a 52 — de sorte qu'un graphique à 52 colonnes fixes décale une semaine tous les cinq ou six ans environ.

Articles qui pourraient t'intéresser

Tous les guides
ExplicationLire et écrire l'heure militaire américaine0800 n'est ni « huit heures » ni « 08:00 » : c'est « zero eight hundred », avec une lettre de fuseau à la fin. Les quatre chiffres, la prononciation, minuit à 0000, la querelle du 2400, et pourquoi la notation sur 12 heures ne peut pas trancher midi.ExplicationTélétravailler depuis un autre pays : où l'impôt est réellement dûLa règle des 183 jours est la phrase la plus répétée et la moins comprise du travail transfrontalier. Elle vient d'un seul article d'un seul modèle de convention, elle a trois conditions et non une, et elle ne décide rien du tout sur la sécurité sociale, la paie ou l'exposition de ton employeur. Voici ce que chaque règle teste réellement.ExplicationComment fonctionne l'heure d'été : on avance, puis on reculeL'heure d'été décale les horloges d'une heure au printemps et les recule en automne. On avance/on recule expliqué, pourquoi un jour fait 23 h et un autre 25, et pourquoi les dates US et UE diffèrent.ExplicationQu'est-ce qu'un timestamp Unix ?Un timestamp Unix compte les secondes depuis le 1er janvier 1970 UTC. Pourquoi les ordinateurs l'utilisent, comment le convertir, et le bug de 2038.TutorielComment convertir les fuseaux horaires : décalages UTC, changement de jour et heure d'étéConvertir entre fuseaux horaires revient à ajouter ou soustraire la différence des décalages UTC, puis à gérer un éventuel changement de jour. La méthode, un exemple et le piège de l'heure d'été.TutorielComment calculer ton âgeSoustrais ton année de naissance de l'année en cours, puis retire un si ton anniversaire n'est pas passé. Voici la règle, l'erreur courante et comment obtenir un âge exact.

Outils similaires

Tout ce qui suit décrit ce que font ces quatre outils aujourd'hui, vérifié en exécutant leur propre code sur les entrées exactes reproduites dans chaque article — et non ce qu'une norme leur imposerait. Quand un outil se trompe sur un cas, c'est dit franchement plutôt que contourné, et rien n'a été modifié pour qu'un article se lise mieux. Deux conséquences. Passe toute transformation sur une copie d'abord et compare les deux bouts : un outil de texte qui supprime quelque chose ne le dit pas. Et considère un secret comme partagé dès qu'il quitte la page — le coller dans une conversation, un ticket ou un dépôt le brûle, aussi bien ait-il été généré.

Sources

Tu as repéré une erreur dans cet article ?