- Lorsqu’il s’agit de représenter la date et l’heure, RFC 3339 se rapproche d’un sous-ensemble restreint, facile à utiliser sur le web et Internet, tandis que ISO 8601-1:2019 couvre un ensemble de formats bien plus large
- Le périmètre de comparaison est limité à ISO 8601-1:2019, et les expressions supplémentaires d’ISO 8601-2:2019 comme les saisons, ensembles, qualificatifs d’incertitude ou l’arithmétique des dates ne sont pas encore reflétées dans le tableau
- Les deux standards traitent ensemble des formats de base de date et d’heure largement utilisés, comme
2026-06-26,14:08:00Z,2026-06-26T14:08:00Zet les offsets+00:00 - ISO 8601 couvre aussi les siècles, décennies, jours ordinaux, dates par semaine, heures abrégées, décimales avec virgule, périodes (
P1Y) et intervalles (2026-06-26/P1Y), alors que RFC 3339 les exclut pour la plupart dans le tableau - Pour la notation Date-Time, des différences comme le séparateur
T, la casse, ou l’offset-00:00déterminent concrètement la compatibilité entre parseurs
Périmètre de comparaison et hypothèses
- Le tableau des formats n’est pas une liste exhaustive
- Le standard visé est ISO 8601-1:2019
- Il existe des différences importantes avec les éditions précédentes et les brouillons
- ISO 8601-2:2019 inclut des expressions supplémentaires, mais elles ne sont pas encore reflétées sur cette page
- Groupes infra-annuels, par exemple les saisons
- Unités de regroupement
- Ensembles
- Qualificatifs d’incertitude
- Arithmétique des dates
- RFC 3339 propose que des sous-standards puissent remplacer
Tpar un autre caractère, mais ne donne comme exemple que le caractère espace - Chaque standard définit des formats selon un usage donné, et les autres formats ne sont pas recommandés
ISO 8601 est plus large pour les notations de date
- RFC 3339 et ISO 8601 prennent tous deux en charge les dates année-mois-jour comme
2026-06-26 - ISO 8601 couvre davantage de représentations de date que RFC 3339
- Siècle :
20 - Décennie :
202 - Année :
2026 - Année-mois :
2026-06 - Jour ordinal :
2026-177 - Date par semaine :
2026-W26,2026-W26-5 - Format de base :
20260626,2026177,2026W26,2026W265
- Siècle :
- Dans le tableau, RFC 3339 n’autorise pas ces formats de date propres à ISO
Différences dans la notation de l’heure
- Les deux standards autorisent les heures à la seconde avec offset de fuseau horaire comme
14:08:00Z,14:08:00+00:00et14:08:00.372+00:00 - RFC 3339 ne distingue pas les majuscules et minuscules, si bien que
TetZpeuvent aussi s’écriretetz- Les éditions précédentes d’ISO 8601 ne distinguaient pas non plus la casse
- ISO 8601 permet d’ajouter une partie fractionnaire à la plus petite unité de temps
- Le tableau montre surtout des exemples avec un seul chiffre après la décimale, mais le standard autorise une précision arbitraire
- La virgule et le point sont tous deux admis comme séparateurs décimaux, et sont interchangeables dans tous les formats
- ISO 8601-1:2019 autorise l’omission de
Tdans les expressions d’heure seules lorsque cela ne crée pas d’ambiguïté - ISO 8601 prend en charge des représentations abrégées, de base ou à décimale avec virgule comme
14,14:08,14:08:00,140800,T14:08:00,14:08:00,372 - RFC 3339 autorise l’offset
-00:00comme dans14:08:00-00:00, alors que dans le tableau ISO 8601 ne l’autorise pas
T et les séparateurs dans Date-Time
- RFC 3339 et ISO 8601 autorisent tous deux des Date-Time comme
2026-06-26T14:08:00Zet2026-06-26T14:08:00+00:00 - Dans la représentation Date-Time d’ISO 8601,
Test toujours obligatoire- Les éditions précédentes autorisaient aussi l’omission de
Tdans Date-Time - Même dans les éditions précédentes, l’insertion de caractères de remplacement comme un espace ou un souligné n’était pas autorisée
- Les éditions précédentes autorisaient aussi l’omission de
- Dans le tableau, RFC 3339 autorise les variantes Date-Time suivantes
tetzen minuscules :2026-06-26t14:08:00z- Séparateur espace :
2026-06-26 14:08:00Z - Séparateur souligné :
2026-06-26_14:08:00Z - Offset
-00:00:2026-06-26T14:08:00-00:00
- ISO 8601 couvre des Date-Time abrégés ainsi que des Date-Time fondés sur le jour ordinal ou la date par semaine, comme
2026-06-26T14,2026-06-26T14:08,2026-06-26T14:08:00,2026-177T14:08,2026-W26-5T14:08
Les périodes et intervalles relèvent surtout d’ISO 8601
- Dans le tableau, les formats de période (Periods) ne sont cochés que pour ISO 8601
- Ex. :
P1Y,P1M,P1W,P1D - Avec heure :
PT1H,PT1M,PT1S - Combinaison :
P1Y1M1DT1H1M1S - Exemples fractionnaires :
P1.5Y,P1,5W,PT1.5S
- Ex. :
- Les formats d’intervalle (Ranges) ne sont eux aussi cochés que pour ISO 8601
- Date et période :
2026-06-26/P1Y - Date et date :
2026-06-26/2026-06-26 - Période et date :
P1Y/2026-06-26 - Date-Time et période :
2026-06-26T14:08/P1DT1H - Intervalles répétés :
R/2026-06-26/P1Y,R10/2026-06-26/P1Y
- Date et période :
Clés de format et outil de test
- Le tableau des formats utilise des clés de format comme
%Y,%M,%D,%h,%m,%s%Y: Year%M: Month%D: Day%V: Week Year%W: Week%w: Week Day%O: Ordinal Day%h: Hour%m: Minute%s: Second%u: Microsecond%n: Nanosecond%Z: heure de fuseau avec+ou-%z: minute de fuseau horaire
- Le validateur de formats vérifie seulement si le format saisi correspond à l’un des formats du tableau
- Il ne teste pas tous les formats possibles
- ISO 8601 as a Service est un service en bêta-test
- Il prend actuellement en charge seulement Date, Time et DateTime
- Period et Range ne sont pas pris en charge
- Le code source est publié sur GitHub
1 commentaires
Avis sur Hacker News
Il est étrange qu’il n’existe aucun moyen de spécifier une date/heure future dans un fuseau horaire donné. Par exemple, on peut vouloir planifier une réunion le 1er juillet 2030 à 18 h, heure locale de Londres, et il faudrait que cela reste « 18 h à Londres », quelles que soient les modifications des règles du fuseau horaire britannique d’ici là
Le Royaume-Uni utilise actuellement, en gros, Z+00:00 de novembre à mars et l’heure d’été Z+01:00 d’avril à octobre[0], mais d’ici 2030 il pourrait adopter l’heure d’Europe centrale[1], retenter la British Double Summer Time[2] ou supprimer l’heure d’été. Le même « 18 h » pourrait donc varier fortement par rapport à un epoch donné
Je veux mettre dans un événement de calendrier « 18 h selon l’heure de Londres à ce moment-là », mais il n’existe pas de manière standard et interopérable de représenter 2030-07-01 18:00:00 Europe/London
[0] https://en.wikipedia.org/wiki/British_Summer_Time
[1] https://en.wikipedia.org/wiki/Central_European_Time
[2] https://en.wikipedia.org/wiki/British_Summer_Time#Periods_of...
tzentre crochets après une chaîne RFC 3339, et pour exprimer une heure locale il faut aussi fournir une estimation du décalage UTCPar exemple,
2030-07-01 18:00:00 Europe/Londondevient2030-07-01T18:00:00+01:00[Europe/London]. Si les règles britanniques changent avant cette date, l’horodatage devient « incohérent » et c’est à l’application de décider comment le traiter. En revanche, si l’on met!devant le nom du fuseau horaire entre crochets, il ne faut pas suivre aveuglément le décalage UTC et le problème doit être détectéCe format d’horodatage étendu est aussi utilisé par la bibliothèque Temporal proposée pour JavaScript[1], et la fonction de parsing
ZonedDateTime.from()[2] permet de contrôler, via l’optionoffset, quel côté privilégier dans un horodatage incohérent. Il est également possible d’omettre le décalage UTC et de n’indiquer que le fuseau horaire, mais la documentation avertit que l’heure répétée lors du passage à l’heure d’été est ambiguë[0] https://www.ietf.org/archive/id/draft-ietf-sedate-datetime-e...
[1] https://tc39.es/proposal-temporal/docs/strings.html#iana-tim...
[2] https://tc39.es/proposal-temporal/docs/ambiguity.html#ambigu...
Mais il n’est pas inimaginable qu’entre-temps l’Écosse organise un nouveau référendum d’indépendance et rejoigne l’heure d’Europe centrale, ou crée une Scottish Standard Time
2023-11-05 01:30:00 America/New_Yorkcorrespond à l’un de deux instants différentsDans un calendrier, « la même heure à l’horloge murale » est généralement le sens recherché, donc c’est légitime, mais il y a des difficultés d’interface pour gérer les heures bizarres, et l’on peut vouloir intégrer à la syntaxe une façon de lever l’ambiguïté. Heureusement, ces transitions ont généralement lieu au milieu de la nuit, mais j’ai déjà vu ce cas dans un contexte professionnel réel
Si vous invitez quelqu’un dont le fuseau horaire n’a pas d’heure d’été, l’heure bougera dans son calendrier, et il arrive que des collègues internationaux doivent faire avec
[0]: https://www.rfc-editor.org/rfc/rfc5545#section-3.3.5
Les formats date-heure courants ont été conçus pour représenter un instant précis, mais dans ce cas cet instant précis n’existe pas encore. Il est fréquent que des spécifications de date/heure aient une structure non triviale : réunion le dernier vendredi de chaque mois, réunion mensuelle commençant le 31 janvier, deux jours avant la fin du trimestre, etc.
Si l’on veut créer une norme couvrant tous les cas que les gens peuvent imaginer, cela risque vite de devenir complexe. Si une simple date, une heure ou un instant ne suffisent pas, il semble inévitable de créer une structure distincte contenant tous les éléments nécessaires
La spécification ISO n’étant pas disponible gratuitement, il vaut généralement mieux suivre la RFC, et comme beaucoup d’implémentations open source reposent aussi sur des brouillons, on peut difficilement dire que ce soit pleinement favorable à l’open source. C’est aussi une lourde charge pour les développeurs open source
Si l’on construit quelque chose qui manipule des dates futures, on finit presque toujours par vouloir stocker l’heure d’horloge murale + le lieu. Malheureusement, il n’existe pas de standard pour cela. En Europe et aux États-Unis, les fuseaux horaires sont assez stables, donc on peut ne pas bien le ressentir, mais dans de nombreuses régions ils changent souvent, si bien que stocker le décalage n’est pas fiable
5 juin 2026 13:30 à l’horloge murale, Pariscorrespond à ce que la plupart des gens veulent dire, et selon ce que l’UE décidera de faire avec l’heure d’été, cela pourra être UTC+2 ou UTC+1. Pour une API qui manipule des instants passés, il suffit d’utiliser un timestamp POSIX en secondes, millisecondes, microsecondes ou nanosecondesiCal ne prend pas non plus en compte le problème d’un lieu réaffecté à un autre fuseau horaire. De plus, un fichier iCal correct contient toutes les données des fuseaux horaires référencés, ce qui est lourd quand on veut simplement produire une seule date-heure
[1] https://icalendar.org/iCalendar-RFC-5545/3-3-5-date-time.htm...
2026-06-05T13:30+0200[Europe/Paris]https://www.ietf.org/archive/id/draft-ietf-sedate-datetime-e...
Un aspect souvent ignoré dans les standards est la représentation des durées
Voir la section 5.5.4.2 “Representation of time-interval by duration only”, page 21, de http://xml.coverpages.org/ISO-FDIS-8601.pdf. Ce serait bien que les parseurs JSON des langages statiques puissent définir un champ comme une durée et le sérialiser dans un format valide
Un exemple de proposition pour Crystal est ici : https://github.com/crystal-lang/crystal/issues/11942
Par exemple, 15 jours, 5 heures et 20 secondes s’écrivent
P15DT5H0M20S, et 7 semainesP7Wdurationdans l’ABNF de l’annexe A de la RFC 3339Par exemple, avec
"duration": { "days": 15, "hours": 5, "seconds": 20 }, le parseur JSON n’a pas besoin de comprendre la signification des données, et un validateur d’entrée peut s’en charger. De toute façon, quelle que soit la manière dont JSON représente ces données, il faudra une étape de conversion susceptible d’échouerCe qui est « drôle », c’est que RFC 3339 et ISO 8601 contiennent de nombreux formats de date-heure redondants aux objectifs qui se recoupent, mais qu’aucun des deux n’inclut le format le plus utilisé partout et pourtant évident,
2023-09-01 15:30:59De plus, les deux standards sont très peu clairs sur la manière de représenter les dates avant notre ère et les dates postérieures à
9999-12-31ou antérieures à-9999-01-01, et les bibliothèques courantes ne les gèrent généralement pas du tout. Même lorsqu’elles les gèrent, le comportement de00-01-01est pratiquement non définiLe calendrier grégorien est étrange, car l’année qui suit 1 av. J.-C. est 1 ap. J.-C., et presque tous les logiciels, à l’exception des logiciels d’astronomie spécialisés, gèrent mal les dates hors de la plage Unix du futur proche. Même pour des choses qu’il suffirait de stocker sous forme de chaîne, comme les années de naissance et de mort de l’empereur Auguste, ce serait bien que les standards les définissent clairement
Tpar un espace. RFC 3339 fait quelque chose de similaire, de façon beaucoup plus verbeuseIl est aussi difficile d’affirmer que
2023-09-01 15:30:59est le format de date-heure le plus utilisé. La langue la plus utilisée est le chinois, et des séparateurs propres comme dans2023年9月1日y sont courantsISO 8601 autorise aussi, par accord mutuel, les années antérieures à 1582 ou postérieures à 9999. Si elles ne tiennent pas sur quatre chiffres, il faut les faire précéder d’un seul caractère de signe. Ces dates permettent peu de traitements réellement utiles et ne sont donc généralement pas prises en charge, mais j’ai vu un certain nombre de bibliothèques les parser, surtout lorsqu’elles étaient implémentées indépendamment de C
00-01-01est défini comme le 1er janvier de l’an 1 av. J.-C.. ISO 8601 précise clairement que la numérotation des années suit le calendrier grégorien proleptique (proleptic Gregorian calendar), donc elle s’extrapole jusqu’à l’infini négatifJe comprends pourquoi il fallait un caractère qui ne soit pas une espace, mais on aurait au moins pu utiliser un underscore ou un point. Et comme il s’agit d’une chaîne, je ne comprends pas non plus pourquoi on a sacrifié l’universalité du format en limitant la partie année à quatre chiffres
Les années à 6 chiffres donnent l’impression d’être une solution à un problème qui n’arrivera pas vraiment, juste pour paraître tourné vers l’avenir. Il est impensable que la technologie actuelle ou les normes sociales actuelles durent 8000 ans
L’explication selon laquelle l’ISO 8601 utiliserait U+2010 HYPHEN et U+2212 MINUS, et qu’il faudrait utiliser U+2D HYPHEN-MINUS dans les jeux de caractères ne disposant pas de ces caractères, est incorrecte
En réalité, l’ISO 8601 précise que si le jeu de caractères cible est basé sur ISO/IEC 646, il faut utiliser le caractère hyphen-minus dans les deux cas. Unicode en fait clairement partie. Il subsiste une légère ambiguïté, mais l’interprétation est claire pour Unicode, et cela ressemble à une manière indirecte de garantir la compatibilité avec d’autres jeux de caractères basés sur 646 en spécifiant le mappage canonique de 646
Il dit en substance que « tous les caractères utilisés dans les représentations de dates et d’heures appartiennent au répertoire ISO/IEC 646, à l’exception de ‘hyphen’, ‘minus’ et ‘plus-minus’. Dans les environnements utilisant un répertoire de caractères basé sur ISO/IEC 646, ‘hyphen’ et ‘minus’ doivent tous deux être mappés vers ‘hyphen-minus’ »
Unicode étant basé sur ISO 8859, et ISO 8859 étant basé sur ISO 646, l’intention semble bien être d’utiliser U+2D hyphen-minus dans le jeu de caractères Unicode
Sous Windows, le deux-points étant un caractère spécial, il est souvent agaçant qu’il n’existe pas de méthode conforme à RFC 3339 pour mettre une date et une heure dans un nom de fichier
Ce serait bien de pouvoir rester conforme à l’ISO 8601 en utilisant des traits d’union dans la date tout en omettant les deux-points. Par exemple,
20230831T1510-0500est conforme et utilisable dans un nom de fichier, mais2023-08-31T1510-0500et les variantes similaires ne le sont pas. Au passage, la fonctionGet-Datede PowerShell ne comprend pas le premier timestamp, sans traits d’union ni deux-pointsC’est une excellente visualisation de ce sujet
Pour séparer la partie date de la partie heure, je préfère une espace ou un underscore à
T, mais pour éviter les problèmes avec les traitements qui ne gèrent que l’ISO 8601 et par souci de cohérence, je continue généralement à utiliserTT. On ne risque pas de découper accidentellement ce genre de chaîne surTDeux choses m’intriguent. D’abord, quelle est la justification des années sur 6 chiffres ? Aucun système conçu aujourd’hui n’existera encore dans 100 000 ans, non ?
Ensuite, l’ISO 8601 est très répandue, mais RFC 3339 est-elle aussi beaucoup utilisée et adoptée dans les systèmes réels ?
timede Golang etChronode Rust disposent d’outils intégrés pour gérer RFC 3339, mais pas RFC 8601De mémoire, RFC 8601 avait des problèmes d’ambiguïté absents de RFC 3339, et je crois que Python a aussi eu pour cette raison des problèmes d’aller-retour de dates
Il n’existe pas de format où le fuseau horaire est indiqué sur quatre chiffres sans deux-points, alors que
date +%zrenvoie±NNNN%:zexiste. À ce sujet, on peut aussi apprendre àdateà afficher cela par défaut : https://gist.github.com/d081dad407432d53172e30d0d35c39db$ date2023-08-31T11:15:00-07:00±NNNNest valide sans deux-points lorsqu’il est utilisé dans le cadre du « format de base ». Autrement dit, il ne doit y avoir ni traits d’union ni deux-points nulle part dans le format completLes deux formes suivantes sont donc équivalentes et toutes deux valides :
2023-09-01T09:40:01+08:0020230901T094001+0800