Convertisseur d’horodatage Unix

Convertissez un horodatage Unix en date dans tout fuseau horaire, et inversement : secondes ou millisecondes détectées, avec ISO 8601 et le temps écoulé.

Temps Unix actuel
Détection…
Entrée

Qu’est-ce qu’un horodatage Unix

Un horodatage Unix — aussi appelé temps epoch ou temps POSIX — est un nombre unique qui compte les secondes écoulées depuis le 1er janvier 1970 à 00:00:00 UTC, un instant appelé epoch Unix. Parce qu’il s’agit d’un seul entier, sans fuseau horaire, sans calendrier et sans mise en forme, c’est le format vers lequel se tournent les ordinateurs dès qu’un instant doit être stocké, trié, comparé ou transmis sur un réseau. C’est ce qui se cache derrière la colonne « created_at » de votre base de données, derrière les claims « iat » et « exp » d’un JWT, derrière le mtime d’un fichier et derrière les horodatages de presque tous les journaux que vous lirez.

La contrepartie, c’est qu’un nombre brut ne dit rien à un être humain. 1716197600 est un instant parfaitement valide, mais vous ne pouvez pas dire d’un coup d’œil s’il s’agit de mardi dernier ou d’il y a trois ans. C’est cette traduction, dans les deux sens, que fait cet outil.

Secondes ou millisecondes : l’ambiguïté qui mord

La convention Unix d’origine compte des secondes entières, et c’est ce que renvoient date +%s dans un shell, time() en PHP et time.time() en Python une fois tronqué. JavaScript, Java et bien d’autres comptent en millisecondes : Date.now() renvoie un nombre mille fois plus grand. Les deux s’appellent « horodatage », et les confondre est l’un des bugs de date les plus répandus qui soient.

La panne est silencieuse plutôt que bruyante. Lisez une valeur en millisecondes comme des secondes et votre date atterrit des dizaines de milliers d’années dans le futur ; lisez une valeur en secondes comme des millisecondes et tout s’effondre en janvier 1970. Ni l’un ni l’autre ne lève d’erreur : vous obtenez simplement une date fausse qui a toutes les apparences d’une vraie.

Cet outil devine d’après l’ordre de grandeur du nombre, puis vous dit ce qu’il a deviné, juste à côté du résultat. Les secondes epoch d’aujourd’hui comptent dix chiffres et les millisecondes treize, si bien que la déduction est presque toujours juste — mais « presque » ne suffit pas pour une valeur que vous vous apprêtez à coller dans un rapport de bug, et c’est pourquoi la lecture retenue est toujours visible et toujours à un clic d’être changée.

Fuseaux horaires, UTC et pourquoi « local » est glissant

Un horodatage Unix n’a pas de fuseau horaire. Il identifie un instant : 1716197600 est 2024-05-20T09:33:20Z, et ce même instant est simultanément 10:33 à Londres, 12:33 à Jérusalem et 18:33 à Tokyo, car ce jour-là Londres et Jérusalem sont à l’heure d’été et le Japon n’en a aucune. Le fuseau horaire ne fait pas partie de la valeur : c’est la lentille à travers laquelle vous la regardez.

C’est pourquoi cet outil montre plusieurs lentilles à la fois. UTC est la référence neutre sur laquelle s’accordent tous les serveurs et tous les journaux. Votre heure locale est celle que signale votre propre appareil, affichée avec le nom de son fuseau (par exemple Europe/Berlin) pour que vous sachiez toujours quelle lentille l’a produite : la détection se fait dans votre navigateur, donc un visiteur à Berlin voit l’heure de Berlin et un visiteur à Tokyo celle de Tokyo. La troisième ligne est le fuseau de votre choix dans la base de données IANA complète — c’est celle qu’il vous faut quand vous lisez le journal d’un serveur situé ailleurs.

  • UTC — la référence sur laquelle tous les systèmes s’accordent, et ce qu’il faut stocker et journaliser.
  • Local — le même instant tel que votre appareil le voit, étiqueté avec le fuseau détecté.
  • Un fuseau de votre choix — pour lire les journaux et les traces de machines situées ailleurs.
  • ISO 8601 — le format texte d’échange, p. ex. 2024-05-20T09:33:20.000Z.
  • Relatif — « il y a 3 heures », pour saisir rapidement à quel point c’est récent.

Les décalages sont affichés à côté de chaque heure (+03:00, -04:00) car ils ne sont pas fixes : la plupart des fuseaux se décalent d’une heure pour l’heure d’été, si bien qu’un même fuseau peut produire des décalages différents selon la période de l’année. Une date proche d’un changement d’heure est précisément là où le calcul à la main déraille.

Travailler avec le temps epoch en pratique

Chaque langage et chaque shell a sa façon de produire et de lire des valeurs epoch. Voici celles qui méritent d’être retenues :

date +%s                         # shell : heure actuelle en secondes
date -d @1716197600              # shell (GNU) : des secondes vers une date
Date.now()                       # JavaScript : heure actuelle en MILLIsecondes
new Date(1716197600 * 1000)      # JavaScript : des secondes vers un Date
time.time()                      # Python : secondes, en flottant
datetime.fromtimestamp(1716197600, tz=timezone.utc)
SELECT EXTRACT(EPOCH FROM now()) -- PostgreSQL : secondes

Une règle empirique qui évite l’essentiel des douleurs liées aux dates : stockez et transmettez les instants en UTC — soit un entier epoch, soit une chaîne ISO 8601 — et ne convertissez vers un fuseau local qu’au tout dernier moment, quand vous les affichez réellement à quelqu’un. Formater trop tôt, c’est ainsi qu’un bug de fuseau horaire finit cuit dans vos données au lieu de rester dans la couche d’affichage.

Autre chose à savoir : un compteur de secondes signé sur 32 bits arrive à saturation le 19 janvier 2038, le « problème de l’an 2038 ». Les systèmes modernes utilisent des valeurs 64 bits et ne risquent rien, mais les vieux équipements embarqués et les anciennes colonnes de bases de données sont justement là où vous pouvez encore le rencontrer.

Qu’est-ce qu’un epoch, et pourquoi tout horodatage ne part pas de 1970

Un epoch, en ce sens, n’est rien d’autre qu’un zéro choisi : l’instant à partir duquel un compteur est défini comme commençant. L’epoch Unix, c’est le 1er janvier 1970 à 00:00:00 UTC, et il a été choisi parce que c’était une date ronde et commode, non parce qu’il se déduirait de quoi que ce soit : rien dans le format lui-même n’exige ce jour-là. Le premier Unix comptait des soixantièmes de seconde depuis un zéro bien plus proche, et le manuel de la troisième édition a dit sans détour pourquoi cela ne pouvait pas tenir : trente-deux bits de soixantièmes garantissent une crise tous les 2,26 ans, soit environ tous les 828 jours. Des secondes entières dans les mêmes trente-deux bits portent à cent trente-six ans, ou soixante-huit si le compteur est signé, ce qui est la date de 2038 ci-dessus.

Cette histoire est la raison de vérifier un nombre long avant de lui faire confiance. D’autres systèmes comptent depuis d’autres zéros et à d’autres résolutions, et lire l’un d’eux comme des secondes Unix ne vous décale pas de quelques heures : cela vous décale de siècles. Voici ceux que vous rencontrerez le plus probablement :

  • Windows FILETIME — des tics de cent nanosecondes depuis le 1er janvier 1601 UTC. Divisez par dix millions et retranchez 11644473600 pour obtenir des secondes Unix ; l’instant 1716197600 utilisé tout au long de ce guide vaut 133606712000000000 dans ce schéma.
  • .NET DateTime.Ticks — le même tic de cent nanosecondes, mais compté depuis le début de l’an 1. L’epoch Unix lui-même se situe à 621355968000000000 tics, et c’est le nombre à retrancher avant de diviser.
  • La date de référence d’Apple — des secondes depuis le 1er janvier 2001 UTC, qu’utilisent Cocoa et Core Data. Ajoutez 978307200 pour obtenir des secondes Unix : 1716197600 y vaut 737890400.
  • Les numéros de série d’Excel — des jours plutôt que des secondes, comptés depuis le 30 décembre 1899, parce qu’Excel traite 1900 comme une année bissextile, ce qu’elle n’était pas.
  • Le temps GPS — des secondes depuis le 6 janvier 1980, comptées sans jamais sauter une seconde intercalaire, si bien que le temps GPS et UTC ne concordent plus.

Ce dernier point renvoie à quelque chose de vrai de la valeur Unix elle-même : ce n’est pas la lecture d’un chronomètre. POSIX la définit comme une valeur qui approche les secondes écoulées depuis l’epoch et exige que chaque jour, sans exception, soit compté pour exactement 86400 secondes — les secondes intercalaires insérées dans UTC ne sont donc pas comptées du tout. L’écart entre deux horodatages Unix est par conséquent le nombre de secondes de calendrier qui les séparent et non le nombre de secondes réellement écoulées, et la valeur se comprend le mieux comme l’encodage d’une lecture de calendrier en UTC. C’est aussi pourquoi aucun horodatage ne désigne jamais une seconde intercalaire : l’encodage n’a pas de place pour elle.

D’une date vers une valeur epoch : le shell, JavaScript et Python

Le bloc ci-dessus transforme une valeur epoch en quelque chose de lisible. Le sens inverse — une date que vous avez déjà, sous forme de texte ou de suite de nombres, transformée en valeur epoch — est l’endroit où vivent les bugs de fuseau horaire, car chacun de ces langages suppose silencieusement un fuseau quand le texte n’en nomme aucun. Voici le même travail de trois façons, sur l’instant 2024-05-20T09:33:20Z de ce guide. Les lignes de shell sont le date de GNU ; celui de BSD et de macOS prend d’autres options.

date -u -d '2024-05-20 09:33:20' +%s     # 1716197600 — -u lit le texte comme de l’UTC
date -d '2024-05-20 09:33:20 UTC' +%s    # la même chose, le fuseau nommé dans le texte
date -d '2024-05-20 09:33:20' +%s        # ni l’un ni l’autre : le fuseau de votre machine
Date.parse('2024-05-20T09:33:20Z') / 1000    // 1716197600 — c’est le Z qui en fait de l’UTC
new Date('2024-05-20T09:33:20Z').getTime()   // le même instant en millisecondes
Date.parse('2024-05-20 09:33:20')            // sans Z : le fuseau de votre machine
from datetime import datetime, timezone
int(datetime(2024, 5, 20, 9, 33, 20, tzinfo=timezone.utc).timestamp())   # 1716197600 — conscient du fuseau
int(datetime.fromisoformat('2024-05-20T09:33:20+00:00').timestamp())     # la même chose, depuis une chaîne
int(datetime(2024, 5, 20, 9, 33, 20).timestamp())                        # naïf : le fuseau de votre machine

Le schéma est identique dans les trois cas : nommez le fuseau, ou vous héritez de celui sur lequel la machine est réglée. Un nombre juste sur votre portable et faux de plusieurs heures sur celui d’un collègue, c’est presque toujours cela, et c’est pourquoi l’outil ci-dessus affiche UTC et votre lecture locale côte à côte au lieu d’en choisir une pour vous. Si vous avez déjà le nombre et voulez le vérifier à l’œil, collez-le dans le champ en haut de cette page.

Questions fréquentes

Comment sait-il si mon nombre est en secondes ou en millisecondes ?
D’après son ordre de grandeur : les valeurs inférieures à environ 1e11 sont lues comme des secondes, les plus grandes comme des millisecondes. Aujourd’hui, cela sépare proprement les secondes à dix chiffres des millisecondes à treize. La lecture retenue est affichée à côté du résultat et vous pouvez la changer d’un clic : la déduction ne vous est jamais cachée.
Quel fuseau horaire compte comme « local » ?
Celui que signale votre propre appareil, détecté dans votre navigateur et affiché par son nom pour lever tout doute. C’est votre fuseau, pas celui du site : un visiteur à Berlin voit l’heure de Berlin et un visiteur à Tokyo celle de Tokyo.
Puis-je reconvertir une date en horodatage ?
Oui. Le même champ accepte les deux sens : saisissez un nombre et vous obtenez une date ; saisissez une date comme 2024-05-20 ou 2024-05-20T09:33:20Z et vous obtenez la valeur epoch. Il n’y a aucun mode à changer.
Gère-t-il les dates antérieures à 1970 ?
Oui. Les horodatages antérieurs à l’epoch sont simplement négatifs — -86400 correspond au 31 décembre 1969 — et les valeurs négatives sont acceptées et converties normalement.
Pourquoi mon horodatage affiche-t-il une date différente de celle attendue ?
Presque toujours pour l’une de ces deux raisons : la lecture secondes/millisecondes n’est pas celle que vous supposiez (regardez l’étiquette et changez-la), ou vous comparez une valeur UTC à une attente en heure locale. L’outil affiche les deux lignes côte à côte pour que vous voyiez laquelle des deux est en cause.
Qu’est-ce que le problème de l’an 2038 ?
Les systèmes qui stockent les secondes epoch dans un entier signé sur 32 bits débordent le 19 janvier 2038 et basculent vers un nombre négatif, donnant des dates en 1901. Tout ce qui utilise des valeurs 64 bits — c’est-à-dire presque tout ce qui est moderne — n’est pas concerné, mais les systèmes embarqués hérités et les anciennes colonnes de bases de données peuvent encore être exposés.
Pourquoi mon horodatage fait-il dix-huit chiffres ?
Parce que ce n’est probablement pas un horodatage Unix. Les secondes Unix font aujourd’hui dix chiffres et les millisecondes treize ; dix-huit, c’est l’allure d’un tic de cent nanosecondes, ce que compte Windows FILETIME depuis 1601 et ce que compte .NET depuis le début de l’an 1. Seize chiffres est l’autre cas fréquent : le même instant en microsecondes. La section sur les epochs ci-dessus donne la constante à retrancher dans chaque cas.
Comment convertir une date en horodatage Unix en Python ?
Construisez un datetime conscient du fuseau — un datetime qui porte un tzinfo — appelez sa méthode timestamp, puis tronquez le résultat en entier. Le bloc de code ci-dessus contient la ligne, et la même section montre le même travail dans le shell et en JavaScript. Toute la difficulté tient au tzinfo : omettez-le et Python lit vos nombres comme l’heure locale de la machine et renvoie une autre valeur sans vous le dire.
L’horodatage que je saisis est-il envoyé quelque part ?
Non. L’analyse, la conversion et la mise en forme s’exécutent entièrement dans votre navigateur, en s’appuyant sur la prise en charge des dates et des fuseaux horaires de la plateforme elle-même. Rien de ce que vous saisissez ne quitte votre appareil.

Outils connexes