Aller au contenu
LeedyBox
Soutenir

Les timestamps Unix expliqués

Un timestamp Unix est un nombre unique qui désigne un instant. Il est facile à stocker et à comparer, mais les unités, les fuseaux horaires et les formats texte sont à l’origine de nombreuses erreurs de conversion.

Qu’est-ce que le temps Unix ?

Le temps Unix (aussi appelé epoch time ou temps POSIX) compte les secondes écoulées depuis 1970-01-01 00:00:00 UTC, l’origine du temps Unix (l’epoch). 0 correspond à cette origine, 1700000000 à 2023-11-14 22:13:20 UTC, et les valeurs négatives désignent des instants antérieurs à 1970 : -1 correspond à 1969-12-31 23:59:59 UTC.

Ce nombre ne contient aucun fuseau horaire : il désigne le même instant partout, ce qui le rend pratique pour stocker, trier et comparer des événements.

Le temps Unix ignore les secondes intercalaires : chaque jour compte exactement 86 400 secondes. Lorsqu’une seconde intercalaire est ajoutée à UTC, les systèmes répètent une seconde ou l’étalent sur une période plus longue (« smearing ») : un écart qui englobe une seconde intercalaire est donc inférieur d’une seconde au temps physiquement écoulé.

Secondes, millisecondes, microsecondes ou nanosecondes ?

De nombreux systèmes comptent dans des unités plus petites, et le nombre n’indique pas laquelle. Un même instant peut ainsi apparaître sous la forme de quatre nombres très différents :

Unité2023-11-14 22:13:20 UTCChiffres (2001–2286)Fréquent dans
Secondes170000000010date +%s, de nombreuses API, le claim exp des JWT
Millisecondes170000000000013Date.now() en JavaScript, System.currentTimeMillis() en Java
Microsecondes170000000000000016Certaines bases de données et certains systèmes de journalisation
Nanosecondes170000000000000000019UnixNano() en Go, time.time_ns() en Python

Compter les chiffres est la vérification la plus rapide pour les dates actuelles. Le convertisseur de LeedyBox repose sur la même idée : les valeurs jusqu’à 1011 sont lues comme des secondes, jusqu’à 1014 comme des millisecondes, jusqu’à 1017 comme des microsecondes, et les valeurs plus grandes comme des nanosecondes. Cette règle empirique ne fonctionne pas pour les dates éloignées d’aujourd’hui : vérifiez donc l’unité lorsqu’un résultat paraît étrange.

La précision compte aussi. Les nombres JavaScript ne représentent exactement les entiers que jusqu’à 253 (environ 9 × 1015) : une valeur en nanosecondes comme 1700000000123456789 perd donc ses derniers chiffres lorsqu’elle est lue comme un nombre ordinaire. Conservez ces valeurs sous forme de chaînes ou utilisez BigInt ; le convertisseur le fait en interne. Pour lire le claim exp d’un jeton, décodez-le avec l’outil Base64 / URL / JWT.

Fuseaux horaires et heure d’été

Pour afficher un timestamp sous forme de date et d’heure, il faut un fuseau horaire. UTC sert de référence ; l’heure locale y ajoute un décalage, par exemple +09:00 à Séoul ou −05:00 à New York en hiver.

Préférez les noms de fuseaux IANA, comme Asia/Seoul ou America/New_York, aux décalages fixes et aux abréviations : un nom porte l’historique du fuseau et ses règles d’heure d’été, alors qu’une abréviation comme CST désigne plusieurs fuseaux. Ces règles proviennent de la base de données des fuseaux horaires, qui change plusieurs fois par an, et les navigateurs, les systèmes d’exploitation et les langages en embarquent leurs propres copies : les résultats pour des dates passées ou futures peuvent donc différer.

L’heure d’été crée deux cas délicats lorsque vous convertissez une heure locale en timestamp :

  • Heure sautée : lorsque l’heure avance, certaines heures locales n’existent pas. Dans America/New_York, 2026-03-08 02:30 n’existe pas, car les horloges passent directement de 02:00 à 03:00.
  • Heure répétée : lorsque l’heure recule, certaines heures locales se produisent deux fois. 2026-11-01 01:30 survient une première fois en EDT (UTC−04:00), puis de nouveau une heure plus tard en EST (UTC−05:00).

Les bibliothèques ne traitent pas ces cas de la même façon. Le convertisseur de LeedyBox utilise l’heure valide suivante pour une heure sautée (ici 03:30) et la première occurrence pour une heure répétée, et l’explique dans une note. Les tâches planifiées rencontrent le même problème ; voir Comment lire une expression cron.

ISO 8601, RFC 3339 et dates HTTP

Lorsqu’un instant doit être lisible, écrivez-le au format ISO 8601 ou selon son profil plus strict pour Internet, la RFC 3339 :

2023-11-14T22:13:20Z
2023-11-15T07:13:20+09:00
2023-11-14T22:13:20.500Z

Z signifie UTC. Avec Z ou un décalage, la chaîne est sans ambiguïté. Une chaîne sans l’un ni l’autre, comme 2023-11-14T22:13:20, est une heure locale dans un fuseau inconnu, et les analyseurs ne s’accordent pas sur la façon de la lire.

Les en-têtes HTTP comme Last-Modified et Expires utilisent un format plus ancien, dérivé du format de date des e-mails (RFC 2822, aujourd’hui RFC 5322), exprimé en GMT : Tue, 14 Nov 2023 22:13:20 GMT.

Le problème de l’an 2038

De nombreux systèmes anciens stockent le temps Unix dans un entier signé de 32 bits. Sa valeur maximale, 2147483647, correspond à 2038-01-19 03:14:07 UTC. Une seconde plus tard, le compteur déborde et passe à -2147483648, ce qui se lit 1901-12-13 20:45:52 UTC. Les systèmes d’exploitation et les langages actuels utilisent pour la plupart des valeurs de temps sur 64 bits, qui couvrent des centaines de milliards d’années, mais des champs de 32 bits subsistent dans des appareils embarqués, des formats de fichier, des colonnes de bases de données et des protocoles réseau. Si votre code ou vos données stockent des secondes sur 32 bits, planifiez le changement tôt et testez dès maintenant des dates postérieures à 2038.

Les timestamps dans le code et les bases de données

JavaScript travaille en millisecondes :

Math.floor(Date.now() / 1000);                  // temps Unix actuel en secondes
new Date(1700000000 * 1000).toISOString();      // "2023-11-14T22:13:20.000Z"
Date.parse("2026-10-03T09:00:00+09:00") / 1000; // 1790985600

En Python, time.time() renvoie des secondes sous forme de nombre à virgule flottante. Passez tz=timezone.utc, sinon fromtimestamp() renvoie l’heure locale de l’ordinateur sans fuseau :

import time
from datetime import datetime, timezone

int(time.time())                                     # secondes
datetime.fromtimestamp(1700000000, tz=timezone.utc)  # 2023-11-14 22:13:20+00:00
datetime.fromisoformat("2026-10-03T09:00:00+09:00").timestamp()  # 1790985600.0

En SQL, les fonctions diffèrent selon la base de données :

-- PostgreSQL
SELECT extract(epoch FROM now());   -- secondes, avec une partie décimale
SELECT to_timestamp(1700000000);    -- timestamp with time zone
-- MySQL
SELECT UNIX_TIMESTAMP();
SELECT FROM_UNIXTIME(1700000000);   -- dans le fuseau horaire de la session

Pour le stockage, quelques habitudes évitent la plupart des problèmes :

  • Stockez les instants déjà passés en UTC, soit dans une colonne de type timestamp avec fuseau horaire, soit sous forme d’entier 64 bits dont l’unité figure dans le nom de la colonne, comme created_at_ms.
  • Stockez les événements locaux à venir, comme une réunion à 09:00 à Séoul, sous forme de date et d’heure locales accompagnées du nom de fuseau IANA, et calculez le timestamp au moment voulu : un changement de règle ultérieur ne déplacera pas la réunion.
  • Ne mélangez pas les unités dans une même colonne ; une mauvaise unité fausse la valeur d’un facteur 1 000 ou plus.

Questions fréquentes

Pourquoi mon timestamp donne-t-il une date en 1970 ?

La valeur a probablement été lue dans la mauvaise unité : des secondes lues comme des millisecondes tombent en janvier 1970, et des millisecondes lues comme des secondes tombent des dizaines de milliers d’années dans le futur. Comptez les chiffres ou choisissez l’unité dans le convertisseur.

Un timestamp Unix dépend-il de mon fuseau horaire ?

Non. Il compte les secondes depuis un instant fixe en UTC. Seules la date et l’heure affichées pour ce timestamp dépendent du fuseau horaire.

Le temps Unix peut-il représenter une seconde intercalaire ?

Non. Le temps Unix considère que chaque jour dure 86 400 secondes : une heure UTC comme 23:59:60 n’a donc pas de timestamp propre.