Les dates et heures

Les dates sont un concept en apparence simple – on les utilise tout le temps sans trop y réfléchir – mais dont la manipulation contient de nombreuses subtilités. Or, en informatique, tout doit être explicite et rigoureux : on ne peut pas compter sur l’ordinateur pour interpréter les suppositions que l’on ferait dans le programme ou demander s’il a mal compris, contrairement à ce que ferait un humain…

C’est pourquoi l’on va disséquer ici les trois types de dates et leurs notions associées ; la question des calendriers et celle de précision des dates ; et enfin les détails propres à la gestion des dates en informatique.

Les 3 (trois ?!) types de dates

Parce que oui, il y a trois types de « dates », et leur confusion est la source d’une quantité infinie de problèmes en informatique.

Définitions

Définition

Un instant, ou moment est la position d’un évènement dans le temps. Il est absolu1 et indépendant de l’utilisateur.

Ce que ne laisse pas apparaitre cette définition, c’est que le langage naturel ne dispose d’aucun moyen de désigner directement un instant, mis à part des éléments trop relatifs de type « maintenant » ou paraphrases lourdes et spécifiques comme « à l’instant où s’ouvrit la porte ». À la place, on utilise un concept différent, la date :

Définition

Une date est une indication de temps, donnée dans un calendrier particulier avec une certaine précision. Elle peut être dépendante de l’utilisateur.

Ce flou dans la définition d’une date ainsi que des contraintes physiques vont entrainer la séparation du concept en deux entités distinctes.

Concernant la précision, on peut en première approche déterminer si une date est accompagnée d’une indication horaire ou non, mais en réalité l’éventail des précisions possibles est bien plus large. Les notions d’horaires font l’objet d’une section à part.

Les trois types de dates

L’instant

L’instant est à employer dès que l’on doit manipuler la position d’un évènement dans le temps.

C’est sans doute le cas le plus fréquent en informatique, et ne pose théoriquement aucun problème : si le langage naturel ne dispose pas d’outils simples pour déterminer un instant donné, l’informatique le permet.

Quelques exemples d’instants utilisés « directement » en langage courant : « maintenant » (très utilisé, mais très inutile sorti du contexte précis de son usage), « Quand l’arbre fut foudroyé » (désigne un instant très bien identifié… si on sait de quel arbre il s’agit).

La date indépendante de l’utilisateur

Dès que l’on doit présenter une information temporelle à un utilisateur humain, on doit employer une date. Le plus simple – pour le développeur – est de manier une de date indépendante du référentiel de l’utilisateur2, donc une date avec un fuseau horaire explicite – indiqué par un décalage horaire.

Ceci évite d’avoir à connaitre ou supposer le fuseau horaire de votre usager et prévient les malentendus associés.

« Jeudi 17 juin 2021 à 20 h 00 UTC+2 » est un exemple de date indépendante de l’utilisateur.

À propos des fuseaux horaires

Un fuseau horaire peut être défini par un décalage horaire (exemple : UTC+3:00) ou par une zone géographique, qui indique quelle heure légale s’applique (exemple : Europe/Paris). À cause des heures d’été et des modifications ponctuelles des heures légales, on ne peut pas coupler de manière stable un décalage horaire avec une indication géographique de fuseau horaire.

Dans la suite de ce contenu, pour alléger le texte et sauf indication contraire, un « fuseau horaire » s’entend uniquement comme identifié par un décalage horaire numérique.

Carte des fuseaux horaires mondiaux au 5 mai 2021
La carte des fuseaux horaires « normaux » (heures d’hiver le cas échéant) en application au 5 mai 2021. Domaine public.
La date locale, dépendante de l’utilisateur

Seulement, voilà, les dates indépendantes de l’utilisateur ont deux inconvénients :

  1. elles sont très peu naturelles à manipuler ;
  2. certains évènements sont liés à une date en tant que telle et pas à un instant – pensez à une date d’anniversaire par exemple.

C’est pourquoi dans la plupart des cas, les saisies et affichages par l’usager se font via des dates locales, dépendantes d’un référentiel utilisateur. Ce référentiel peut être implicite (une application métier dont on sait qu’elle n’est employée que dans un fuseau horaire connu), ou paramétrable dans les préférences de l’utilisateur – une subtilité que votre programme devra gérer.

« Le 1er janvier 2000 à 0 h 00 », bien qu’étant une date très importante symboliquement, est totalement tributaire de l’utilisateur et n’équivaut à aucun moment spécifique3.

Conversion entre ces concepts

Jusqu’ici, tout peut paraitre simple. Naïvement, on pourrait se dire qu’il suffit de tout stocker dans l’un de ces formats, le plus pratique d’un point de vue technique, et de tout convertir dans le bon « type de date » quand on en a besoin. Seulement, la dure réalité est :

Il n’existe aucune conversion simple entre ces différents types de dates.
La confusion entre ces concepts, et les difficultés et erreurs de transformation qui en découlent, sont la source d’énormément de problèmes informatiques.

Conversion entre « instant » et « date indépendante de l’utilisateur »

Une date indépendante de l’utilisateur, si elle est complète, correspond toujours à un seul instant.

Par contre un instant peut être exprimé sous la forme de plusieurs dates avec fuseau horaire – une par fuseau horaire.

L’instant symbolisé par « le 4 mai 2005 à 03 heures 02 minutes et 01 seconde à UTC+0 » est aussi représenté par :

  • « le 4 mai 2005 à 04 heures 02 minutes et 01 seconde à UTC+1 » ;
  • par « le 3 mai 2005 à 23 heures 02 minutes et 01 seconde à UTC-4 » ;
  • ou même par « le 4 mai 2005 à 08 heures 47 minutes et 01 seconde à UTC+5:45 » – parce que le décalage n’est pas obligatoirement un nombre entier d’heures.
Conversion qui implique une date dépendante de l’utilisateur

Une conversion entre d’une part, un instant ou une date avec fuseau horaire, et d’autre part une date dépendante de l’usager, se heurte aux problématiques de définition du fuseau horaire à utiliser.

Pour commencer, cette conversion n’est pas possible si la date ne vise pas à représenter un instant. Si mon anniversaire est le 4 mai, il est le 4 mai quel que soit le fuseau horaire dans lequel je me trouve et quel que soit le fuseau horaire dans lequel se trouve mon interlocuteur.

D’autre part, la récupération du décalage horaire à employer peut être particulièrement complexe :

  • Il peut changer selon l’utilisateur de l’application.
  • Il peut changer selon la date : l’utilisateur ne fournit pas directement un décalage horaire en « nombre d’heures et de minutes de décalage à appliquer », mais en « fuseau horaire légal à tel endroit ». Or, certains pays ou régions utilisent des heures différentes l’été et l’hiver – ce qui doit être pris en compte.
  • Pire, les dates d’application des heures d’été et d’hiver peuvent évoluer (et même apparaitre et disparaitre).
  • De même, l’heure légale applicable dans un territoire donné peut changer au cours du temps. Dans les exemples très récents, la Corée du Nord est passée de UTC+9:00 à UTC+8:30 le 15 aout 2015, puis est revenue à UTC+9:00 le 5 mai 2018 – la Corée du Sud avait fait les mêmes modifications en 1954 et 1961.
  • Enfin, si vous devez gérer des dates anciennes, la notion même de « fuseau horaire » est relativement moderne : elle n’existe pas réellement avant 1858, et n’est généralisée au monde entier qu’à partir de 1929.
Carte des fuseaux horaires en vigueur aux États-Unis d’Amérique en 1913
Carte des fuseaux horaires en vigueur aux États-Unis d’Amérique en 1913, qui sont différents de ceux en application en 2021. CC–0 Owen Blacker
Un outil pour retrouver les décalages horaires : tz database

Lorsque l’utilisateur doit renseigner son fuseau horaire, ou quand on doit convertir des dates dans lesquelles interviennent un fuseau horaire se pose la question suivante : quels sont les décalages horaires correspondants ?

On l’a vu plus haut : non seulement la liste à un instant T est longue et fastidieuse à maintenir, mais en plus elle change régulièrement au cours du temps !

Heureusement il existe un standard de fait, c’est tz database, aussi connue sous les désignations de tzdata, de zoneinfo database ou encore de IANA time zone database. Comme son nom l’indique, c’est une base de données qui identifie quels décalages appliquer en fonction de la zone géographique et de la date. Vous pouvez aller voir son site officiel ou la page Wikipédia anglophone (la version francophone est très légère).

Carte du monde avec le découpage de toutes les zones tzdata existantes
La carte complète des zones tzdata, début 2017. Oui, il y a des zones sur l’océan, ça n’est pas une blague du cartographe – CC BY-SA 4.0 Evan Siroky

Cette base de données est très fiable pour toutes les dates entre 1970 et sa date de dernière mise à jour – l’IANA peut en publier plusieurs moutures par an. En dehors de ces bornes, elle peut contenir des erreurs, ce qui est une bonne raison pour la maintenir à jour. Heureusement, cette tâche est presque toujours confiée au système d’exploitation ou aux frameworks. Par exemple, les mises à jour Java embarquent les dernières versions de tzdata à parution. Cela dit, c’est toujours intéressant de vérifier qui est responsable de cette base de données dans votre système.


  1.  On va laisser de côté ici le cas des relativités restreintes et générales qui casseraient ce paradigme. De toute façon, si vous devez vraiment les gérer, vous ne pourrez pas employer les bibliothèques existantes et standards des langages de programmation.
  2. L’usage d’une date impliquant de recourir à un calendrier et un formatage particulier, toute date est obligatoirement tributaire d’un contexte local qu’il va falloir prendre en compte si votre logiciel a une vocation internationale. Mais une fois que l’utilisateur aura « décodé » le système de date que vous exploitez, la présence du fuseau horaire fera que la date ne sera pas ambigüe. Enfin, pas trop. Le moins possible, en tous cas.
  3. Plus exactement, « Le 1er janvier 2000 à 0 h 00 » correspond à autant d’instants qu’il y avait de fuseaux horaires « en activité » à ce moment là, chaque fuseau horaire ayant atteint « Le 1er janvier 2000 à 0 h 00 » à un instant différent.

Digression sur les calendriers

Dans la grande majorité des cas, le seul calendrier à gérer sera le calendrier grégorien, qui est le standard de fait presque partout, et celui utilisé par défaut dans tous les langages de programmation.

Mais il se peut que vous ayez à gérer d’autres types de calendriers, pour des raisons culturelles, religieuses, ou tout simplement de date.

En ce qui concerne ce dernier point : si vous devez gérer des périodes historiques, le calendrier grégorien n’est réellement entré en usage que le 15 octobre 1582 dans certains pays, mais cette date varie beaucoup selon les régions du monde, et il n’est pas d’usage de l’appliquer de manière rétroactive. Cela donne des situations étranges, comme une nuit du 4 au 15 octobre 1582 en Espagne – le 4 octobre s’entendant selon le calendrier julien, et le 15 selon le calendrier grégorien.

Certains calendriers peuvent utiliser des logiques et des durées de mois et d’année très différentes du calendrier grégorien. En fait, certains calendriers peuvent être imprévisibles parce que basés sur l’observation d’un phénomène naturel.

Exemple : une date, de multiples façons de la nommer
Page de calendrier de Thessalonique de 1896, avec 5 systèmes et 6 langues
Une page de calendrier parue à Thessalonique en 1896. Domaine public.

Cette page de calendrier montre la date du jour pour le même jour dans six langues (turc ottoman, arménien, « hébreu-espagnol », grec, bulgare et français) et surtout cinq systèmes de calendriers différents. Ce jour-là était nommé :

  • 20 Teşrin-i Evvel 1311 dans le calendrier rumi (calendrier julien de l’Empire Ottoman) ;
  • 14 Jumādā al-Ūlā 1313 dans le calendrier islamique ;
  • 14 Cheshvan 5656 dans le calendrier hébraïque ;
  • 20 octobre 1896 dans le calendrier julien ;
  • 1er novembre 1896 dans le calendrier grégorien.

Toutes ces subtilités ont deux implications :

D’une part, à moins d’une très bonne raison – comme faire des calculs spécifiques à un calendrier – toute manipulation de dates supposant un calendrier devrait se faire sur le calendrier grégorien, avec une conversion dans un autre calendrier le plus tard possible, au plus proche de l’affichage à l’utilisateur.

D’autre part, employez des bibliothèques tierces pour gérer les conversions entre calendriers. Gérer un seul calendrier est déjà un champ de mines ; prendre correctement en compte toutes les subtilités de transformation sans savoir très exactement ce que l’on fait, c’est la certitude de se tromper quelque part.

Précision d’une date et dates partielles

Une question de précision

Une date est toujours donnée avec une certaine précision, implicite ou explicite. Cette précision n’a rien à voir avec la durée éventuelle de l’évènement daté.

Par exemple, Iron Maiden :

  • a été fondé en 1975 (précision à l’année, évènement instantané) ;
  • a sorti son album « The Number Of The Beast » le 29 mars 1982 (précision au jour, évènement instantané) ;
  • a commencé sa tournée « Somewhere Back in Time » le 1er février 2008 (précision au jour, évènement de plus d’un an) ;
  • a joué un concert au Hellfest le 24 juin 2018 à 21 h 30 (précision à la minute, évènement de deux heures).

La principale difficulté est que cette précision est rarement explicite, et que la date indiquée peut être plus précise que la date réelle. Par exemple, cette réunion notée pour le 3 juin à 10 h 00 dans votre agenda ne commencera probablement pas exactement à 10 h 00 ce jour-là.

La précision peut aussi dépendre des connaissances de la personne qui mentionne la date : un admirateur saura que Iron Maiden a été fondé en 1975 (précision à l’année), un fan hardcore (ou qui vient de lire l’article Wikipédia) pourra préciser que le groupe a été créé le 25 décembre 1975 (précision à la journée), et un membre fondateur du groupe sera peut-être capable de préciser l’heure de cet évènement particulier. Mais personne ne pourra donner de précision parfaite, parce que par nature, un fait tel que « la création d’un groupe » n’est pas assimilable à un seul instant unique.

La conséquence, c’est qu’il faut choisir une représentation de date dont la précision est cohérente avec la date manipulée. Ça n’a aucun sens d’utiliser une précision à l’année pour traiter des dates de début de réunion ; pas plus que ça n’a de logique de les gérer à la milliseconde près.

  • Un format de date pas assez détaillé va mener à des soucis de précision et de cohérence assez évidents,
  • Un format de date trop précis va surtout poser des problèmes d’ergonomie à l’affichage, et peut fausser les comparaisons.

Les outils informatiques ne comprennent en standard que certains niveaux de précision, en général :

  • À l’année (la date est un simple entier),
  • Au jour,
  • À la seconde,
  • À une subdivision de la seconde qui dépend du langage (généralement la milliseconde ou la nanoseconde, mais certains langages utilisent des subdivisions plus exotiques).

En cas de besoin d’une précision différente, le plus simple est d’employer une représentation de meilleure précision, et d’ignorer les subdivisions non pertinentes, en prenant garde aux effets de bord.

Horloge atomique de référence embarquée dans les satellites Galileo
Cette horloge atomique embarquée dans les satellites Galileo a une précision meilleure que 0,45 nanoseconde d’erreur sur 12 heures – ce qui est mieux que tout ce dont vous devriez avoir besoin un jour. CC BY 3.0 SkywalkerPL.

Les dates partielles

Du fait de leur précision, les dates sont toujours partielles, dans le sens où à partir d’un niveau de précision, les informations associées ne sont plus définies. Par exemple, sur une date précise à la journée, les heures, minutes, secondes et subdivisions ne sont pas déterminées.

Mais il peut arriver que des éléments de date de niveau supérieur soient ignorés, ce qui donne lieu à des choses qui ressemblent à des dates, mais qui n’en sont pas vraiment.

  • « Mon anniversaire est le 30 juin » ressemble à une date avec seulement le mois et le jour du mois de définis, mais pas l’année.
  • « Mon réveil sonne à 7 h 30 » s’apparente à une date, mais avec uniquement l’heure et les minutes de définis.

Ces dates partielles sont utilisées pour les évènements récurrents, et n’ont généralement pas de représentation possible avec les outils standards des langages informatiques.

Usage des dates et heures en informatique

Les instants, la représentation sous forme de timestamp

Les timestamp, l’outil classique pour représenter un instant

Contrairement aux humains, l’informatique peut tout à fait représenter des instants précis sans l’intermédiaire d’une date. Soit directement via une classe (ou toute structure du langage) appelée Instant, soit plus souvent en passant par un timestamp1

Un timestamp n’est rien d’autre qu’un nombre qui donne la quantité d’un intervalle de temps depuis un instant de référence bien connu baptisé epoch2. En prenant l’instant de référence et la durée écoulée depuis (qui peut être négative), on peut ainsi désigner n’importe quel instant sans avoir à faire appel à un système de date avec tous les problèmes que ça implique.

Et comme l’Univers est bien fait, tout le monde s’est mis d’accord pour employer le même intervalle de mesure des durées et le même instant de référence et… hahaha. Non. Évidemment que non.

Les différents systèmes de timestamp

Beaucoup de systèmes ont décidé de créer leur propre structure de timestamp, avec leurs instants de référence particuliers, unité de décompte du temps depuis cet instant, exigences associées (possibilité d’avoir des intervalles partiels ou négatifs)…

Donc, à moins d’avoir la certitude qu’ils utilisent exactement le même système, deux timestamp issus de deux logiciels différents ne seront pas compatibles entre eux.

Pourquoi un tel bazar ? Parce que chaque technique a choisi son origine et son intervalle de temps standard en fonction de ses contraintes spécifiques : plage de dates qu’elle y a besoin de représenter, complexité des calculs à effectuer dessus, espace de stockage du timestamp à l’époque où l’informatique était beaucoup plus limitée qu’aujourd’hui…

Résultat, Wikipedia compte pas moins de 20 epoch différentes dont trois associées à des dates invalides (date inexistante comme le 0 janvier ou utilisation de l’an 1 du calendrier grégorien, qui a commencé en 1582).

Il y a quand même un format de timestamp qui est très largement employé, c’est l’heure Unix, ou heure POSIX, ou unix timestamp, etc. Sa valeur est le nombre de secondes depuis le 1er janvier 1970 à 00:00:00 UTC hors secondes intercalaires.

Exemple : récupérer l’heure Unix en ligne de commande sous Linux :

$ date +%s
1624144581
Intervalles de validité

Les timestamp peuvent avoir des intervalles de validité (premier et dernier instant représentables) assez limités. Ça n’est généralement pas un problème, sauf si vous devez gérer des dates en dehors de la période contemporaine. Les dates du futur peuvent aussi rapidement atteindre un seuil, comme le bug de l’an 2038 si vous utilisez le timestamp POSIX avec un entier signé de 32 bits (ce qui est la façon historique de le gérer).

Vous devriez donc toujours penser à vérifier les dates de validité des timestamp dès que vous l’employez pour manier autre chose que des dates proches de « maintenant ».

Exemples de code

Java possède une classe qui représente un instant :

Instant maintenant = Instant.now();

On peut aussi récupérer directement le timestamp associé (qui ressemble au timestamp POSIX, mais n’est pas strictement identique, même si les raisons recevables d’utiliser cette valeur sont devenues rares :

// Ici en secondes depuis l’epoch Unix :
long timestamp = Instant.now().getEpochSecond();
// On trouve encore souvent l’ancienne méthode, qui donne des millisecondes depuis l’epoch Unix :
long timestamp = System.currentTimeMillis();

Les dates

Ici je vais être obligé d’être flou, parce que les solutions utilisées varient énormément selon le langage de programmation que vous employez (et parfois même la bibliothèque choisie au sein de ce langage).

Représentations internes et méthodes d’utilisation

Tout l’intérêt d’un objet (ou une structure, ou n’importe quoi d’autre selon votre langage) d’une date est de pouvoir ignorer sa représentation interne. Le but est de manipuler les dates exclusivement à l’aide des méthodes dédiées, qui vont gérer proprement tous les pièges et subtilités qui y sont associées.

Cette représentation interne et les méthodes rattachées sont complètement tributaires du langage de programmation. La seule constante, c’est que la représentation standard des dates se fait dans le calendrier grégorien. Si d’autres calendriers sont utilisables, c’est presque toujours une gestion de second ordre (via des conversions ou des appels explicites).

Par exemple, l’objet LocalDate de Java, qui décrit une date (sans heure ni fuseau horaire) dépendante de l’utilisateur emploie cette représentation interne :

    private final int year;
    private final short month;
    private final short day;

Mais son API n’expose pas directement cette représentation interne, en particulier on n’a pas besoin de savoir que month est de type short (aucune méthode de la classe ne renvoie de short), et d’ailleurs la méthode getMonth() a un retour de type Month, qui est une énumération des mois existants du calendrier grégorien.

La représentation d’une date : la chaine de caractères

Ici, il me faut mettre quelque chose au point :

Chaine de caractères ≠ date

Une date exprimée sous la forme d’une chaine de caractères n’est qu’une représentation de cette date parmi d’autres. Les limites de cette représentation ne sont donc pas celles de la date elle-même.

En particulier, les problématiques d’internationalisation ou de tri ne se posent que lorsqu’on manipule la représentation sous forme de chaine de caractères, et pas la date elle-même – à l’exception du choix du calendrier pour certaines opérations.

La transformation d’une date en chaine de caractères ne pose généralement aucune question, à partir du moment où on a étudié ces deux éléments :

  1. On connait le format de date exact voulu en sortie – en prenant compte de toutes les subtilités d’internationalisation susmentionnées ;
  2. On maitrise les méthodes de formatage de dates utilisées par le langage de programmation.

Pour ce second point, là encore : tout le monde a développé son propre système dans son coin, et on peut partir du principe que, en première approche, chaque langage a son propre système de formatage incompatible avec les autres – même s’il y a parfois des ressemblances.

Par exemple, si on veut déclarer un formatage de type « 2021–06–19 12:34:56 », Java demande d’écrire yyyy-MM-dd HH:mm:ss là où PHP demande d’écrire Y-m-d H:i:s et Go 2006-01-02 15:04:05 – trois systèmes complètement différents, donc.

La transformation d’une chaine de caractères en date (typiquement à la lecture de données externes au programme) exige de répondre aux mêmes questions, mais en plus de gérer correctement deux sortes d’erreurs :

  1. Les formats invalides : quels sont les formats considérés comme valables à la saisie, et s’il y en a plusieurs, est-ce certain qu’une même entrée ne peut pas être comprise de deux façons différentes par deux formats acceptables ?
  2. Les chaines qui sont formatées comme des dates valides, mais qui ne correspondent pas à des dates existantes, par exemple un 0 janvier, ou un 29 février les années ordinaires.

Sur le second point, certains langages de programmation ont des méthodes de conversion qui sont tolérantes par défaut, c’est-à-dire qui vont corriger l’entrée pour la faire coïncider avec la date valide « la plus logique » (le 31 décembre de l’année précédente pour un 0 janvier, le 1er mars pour un 29 février d’une année non bissextile, voire le 30 juillet pour une saisie d’un 60 juin…). À vous de vérifier si ce comportement vous convient.

Opérations sur les dates

Il peut être tentant de faire soi-même les différentes opérations sur les dates, surtout quand on manipule un timestamp qui est un simple nombre. Sauf opérations triviales – il n’y en a pratiquement jamais lorsqu’on manie des dates –, c’est la garantie d’avoir une erreur ou un comportement étrange dans un cas particulier.

Ne faites pas d’arithmétique directement sur les dates

Ne faites jamais d’opérations directement sur les dates et timestamp. Utilisez systématiquement les méthodes dédiées de la bibliothèque que vous employez.

C’est beaucoup plus sûr, robuste, et le surcout est négligeable avec les machines actuelles.

Communication entre langages

La norme ISO 8601

Pour transmettre des dates entre des systèmes hétérogènes (c’est-à-dire quand on ne peut pas directement transmettre les types d’instants ou de dates), le moyen le plus simple et le plus fiable est d’utiliser la représentation adéquate selon la norme ISO 8601.

Cette représentation est :

  • Normalisée, ce qui évite tout malentendu ;
  • Implémentée par défaut dans toute bibliothèque de traitement de date vaguement sérieuse – et d’ailleurs vous ne devriez jamais avoir à écrire le format ISO voulu à la main ;
  • Robuste, car elle gère les dates (avec les heures et toutes les subtilités) et les durées, y compris les récurrences.

Il suffit de se mettre d’accord sur la représentation ISO à employer entre les différentes parties, et hop ! La communication se fait toute seule, sans surprise3 !

Si certaines représentations ISO sont assez lisibles pour des humains, ça n’est pas toujours le cas, et il vaut mieux éviter de trop exposer cette norme dans une interface utilisateur.

Quelques exemples de dates au format ISO 8601 :

  • Date seule : 2021-06-19 (date dépendante de l’utilisateur)
  • Date et heure UTC : 2021-06-19T22:51:54+00:00, 2021-06-19T22:51:54Z, 20210619T225154Z (date indépendante de l’utilisateur)
  • Date et heure avec fuseau horaire : 1977-04-22T01:00:00-05:00 (date indépendante de l’utilisateur)

Et un exemple de conversion d’une saisie au format ISO 8601 en une date puis en un instant en Java (OffsetDateTime représente une date avec décalage horaire explicite, donc indépendante de l’utilisateur). On voit que l’API standard suppose implicitement un format ISO 8601 par défaut en entrée.

OffsetDateTime date = OffsetDateTime.parse("2010-01-01T12:00:00+01:00");
Instant instant = date.toInstant();  
API dédiées, conversions automatiques et SQL

Dans certains cas, la transmission entre systèmes informatiques se fait via des API dédiées qui n’utilisent pas de transformation explicite en un format textuel, et donc qui ne permettent pas l’usage de la norme susmentionnée. Un cas classique d’utilisation, c’est la communication avec une base de données, en particulier si l’API employée autorise le recours aux requêtes préparées et de leur passer directement des types temporels.

Ce genre de cas impose de vérifier que les types du langage et de la base de données sont bien équivalents, et que d’éventuelles transformations ne poseront pas de problème.

Un souci habituel, c’est la manipulation d’un instant représenté par une date indépendante de l’utilisateur. Il arrive que le langage appelant emploie une date au fuseau horaire local, par exemple « le 19 juin 2021 à 01 h 00 UTC+02:00 », mais que la base de données stocke cet instant au format UTC, ce qui donnera « le 18 juin 2021 à 23 h 00 UTC ». Ce qui représente bien le même instant… mais cet instant sera associé au jour précédent si des calculs temporels sont faits directement par la base de données !


  1. Une traduction française de « timestamp » serait « horodatage », mais je ne l’ai jamais vue utilisée dans le contexte de l’informatique.
  2. De l’anglais « époque » ou « ère », mais là encore la traduction française n’est pratiquement jamais utilisée dans le monde informatique.
  3. Sauf quand l’une des implémentations les plus connues d’un langage a un bug dans son traitement de la norme ISO 8601. Ici le moteur JavaScript V8, qui est utilisé dans Chrome et NodeJS, entre autres. Mais ça reste un cas rare.

Derrière la notion floue de « date », se cachent donc trois réalités distinctes :

  1. l’instant, qui désigne la position d’un évènement dans le temps, qui ne s’exprime presque jamais en langage naturel, mais qui possède des représentations informatiques ;
  2. la date indépendante de l’utilisateur, associée à un décalage horaire explicite ;
  3. la date dépendante de l’utilisateur, la plus proche de celle utilisée dans le langage naturel et qui peut ne pas équivaloir à un instant spécifique.

Les dates sont exprimées dans un calendrier particulier et ont une précision donnée.

En informatique, les instants peuvent être représentés directement ou par l’un des trop nombreux systèmes de timestamp existants.

Une date, en informatique, est une structure normalement distincte de sa représentation textuelle (sous forme de chaine de caractères). Cette représentation doit tenir compte des contraintes d’internationalisation. Transmettre des dates entre systèmes informatiques devrait se faire selon la norme ISO 8601.

Enfin, les opérations arithmétiques sur les dates ou timestamp devraient être proscrites en faveur des méthodes consacrées des bibliothèques utilisées.