Year 2038 Problem

Le problème de l'an 2038 (Y2K38) expliqué

Le 19 janvier 2038 à 03:14:07 UTC, le timestamp Unix 2 147 483 647 — la valeur maximale d'un entier signé 32 bits — débordera et basculera vers une date de 1901. Voici ce que cela signifie, quels systèmes sont touchés, comment fonctionne la correction par time_t 64 bits et comment tester votre propre code.

Le dépassement en une ligne

Un entier signé 32 bits plafonne à 2 147 483 647. Stockée en secondes Unix, cette valeur est le 19/01/2038 03:14:07 UTC — et une seconde plus tard elle bascule vers -2 147 483 648, qui se lit comme le 13 décembre 1901. Tout système qui conserve encore le temps dans un entier signé 32 bits fera un bond de 137 ans dans le passé à cet instant. La correction tient en un mot : 64 bits. Le tableau ci-dessous montre quels types de stockage sont touchés et lesquels sont déjà sûrs.

Type de stockageDéborde à / date maxSûr après 2038 ?
time_t signé 32 bits / SQL INT2038-01-19 03:14:07 UTCNon
MySQL TIMESTAMP2038-01-19 03:14:07 UTCNon — utiliser DATETIME
32 bits non signé2106-02-07 06:28:15 UTCGagne 68 ans, pas une solution
time_t signé 64 bits / SQL BIGINT~292 milliards d'annéesOui
Flottant 64 bits (JavaScript, Python)année 275 760Oui
MySQL DATETIME (champs compactés)année 9999Oui

Qu'est-ce que le problème de l'an 2038 ?

Les timestamps Unix sont traditionnellement stockés dans un entier signé 32 bits comptant les secondes depuis le 1er janvier 1970 00:00:00 UTC. La valeur maximale d'un entier signé 32 bits est 2 147 483 647 — ce qui correspond au 19 janvier 2038 à 03:14:07 UTC. Une seconde après ce moment, l'entier déborde vers -2 147 483 648. Interprétée comme un timestamp Unix, cette valeur négative correspond au 13 décembre 1901 — projetant les systèmes touchés près de 137 ans dans le passé.

  • 2^31 − 1 = 2 147 483 647 (entier signé 32 bits maximal)
  • 2 147 483 647 comme date = 19 janvier 2038 03:14:07 UTC
  • 2 147 483 647 + 1 déborde vers −2 147 483 648 (la valeur 32 bits la plus négative)
  • −2 147 483 648 comme date = 13 décembre 1901 20:45:52 UTC
  • L'heure locale du dépassement varie : 22:14:07 EST le 18 janvier, 14:14:07 JST le 19 janvier

Quels systèmes sont à risque ?

Le problème touche les systèmes qui stockent les timestamps dans des entiers signés 32 bits :

  • Systèmes embarqués et microcontrôleurs avec un time_t 32 bits
  • Ancien code C et C++ compilé pour des cibles 32 bits utilisant time_t ou int pour les timestamps
  • Anciens noyaux Linux (avant 5.6) sur du matériel 32 bits encore en production
  • Colonnes MySQL TIMESTAMP — limitées au 2038-01-19 ; utiliser DATETIME à la place
  • Certains protocoles réseau et formats de fichiers qui encodent les timestamps sur 32 bits
  • Firmware de systèmes de contrôle industriels et d'objets connectés à durée de vie de plusieurs décennies

Quels systèmes sont sûrs ?

La plupart du code et de l'infrastructure modernes ne sont déjà pas touchés :

  • Tout OS 64 bits — Linux (glibc 2.34+ corrige aussi le matériel 32 bits), macOS, Windows
  • Python — les timestamps utilisent des flottants 64 bits, sûrs bien au-delà de l'an 292 millions
  • JavaScript — Date utilise des flottants IEEE 754 64 bits, sûr jusqu'à l'an 275 760
  • Go et Rust — utilisent int64 pour le temps en interne, sûrs pour des milliards d'années
  • Java — java.time.Instant utilise long (64 bits), sûr jusqu'à l'an ~292 millions
  • PostgreSQL TIMESTAMP — stocke correctement les dates au-delà de 2038
  • MySQL DATETIME — plage 1000-01-01 à 9999-12-31, non touché

MySQL TIMESTAMP et le plafond de 2038

MySQL a deux principaux types de colonnes date-heure qui se comportent très différemment autour de 2038 :

  • TIMESTAMP est stocké en interne comme un entier Unix signé 32 bits — il déborde le 2038-01-19 03:14:07 UTC
  • DATETIME est stocké comme des champs A/M/J h/m/s compactés et prend en charge jusqu'à l'an 9999 — à utiliser pour toute date pouvant dépasser 2038
  • TIMESTAMP convertit aussi implicitement depuis/vers le fuseau de session du serveur ; DATETIME stocke la valeur telle quelle
  • Pour des colonnes epoch brutes, stockez BIGINT plutôt que INT pour que la valeur elle-même ne puisse pas déborder
  • Auditez les schémas existants : SELECT TABLE_NAME, COLUMN_NAME FROM information_schema.COLUMNS WHERE DATA_TYPE = "timestamp"

Linux embarqué et time_t 32 bits

Le plus grand risque Y2038 restant se trouve dans les systèmes embarqués à longue durée de vie : routeurs, contrôleurs industriels, calculateurs automobiles, compteurs intelligents et objets connectés livrés avec des noyaux 32 bits et pouvant rester en service après 2038. La bibliothèque C et tout protocole binaire maison doivent tous deux être propres en 64 bits.

  • glibc a obtenu le time_t 64 bits pour les ABI 32 bits via la macro de build -D_TIME_BITS=64 (glibc 2.34+)
  • musl libc est en time_t 64 bits par défaut depuis la version 1.2.0 (2020)
  • Debian, Ubuntu et OpenWrt ont tous migré leurs ports 32 bits vers le time_t 64 bits
  • Les timestamps de système de fichiers sont un sujet à part : ext2/ext3 utilisent des temps 32 bits ; ext4 prend en charge le 64 bits sur les inodes ≥ 256 octets
  • Pour le matériel encore livré en 2026+, vérifiez que la bibliothèque C et tout format filaire sont en 64 bits

Comment corriger et tester pour Y2038

La correction est toujours la même — élargir le temps à 64 bits — mais elle doit être appliquée à chaque couche qui stocke ou transmet un timestamp : la bibliothèque C, les colonnes de base de données et tout protocole binaire ou format de fichier. Le moyen le plus rapide de trouver un problème est de placer une horloge au-delà de la limite dans un environnement de test et de guetter les dates qui atterrissent en 1901.

  • Compiler le code 32 bits avec -D_TIME_BITS=64 (et -D_FILE_OFFSET_BITS=64) sur glibc 2.34+
  • Utiliser BIGINT, pas INT, pour toute colonne qui stocke des secondes ou millisecondes Unix brutes
  • Préférer DATETIME ou TIMESTAMPTZ à MySQL TIMESTAMP pour les dates pouvant dépasser 2038
  • En test, régler l'horloge du système ou du conteneur sur 2038-01-19T03:14:08Z et vérifier que les dates restent en 2038
  • Vérifier les formats filaires et les en-têtes de fichiers — un OS 64 bits n'aide pas si le champ du protocole est en 32 bits

Bascules apparentées : Y2K, GPS, NTP et 2106

L'an 2038 fait partie d'une famille de bascules à largeur fixe. Chacune vient du fait de tasser une horloge dans trop peu de bits, et connaître les dates aide à repérer la suivante avant qu'elle ne soit livrée :

BasculeDateCause
Y2K2000-01-01Stockage de l'année sur deux chiffres
Bascule de semaine GPS2019-04-06Compteur de semaine GPS sur 10 bits
Bascule d'ère NTP2036-02-07Secondes non signées sur 32 bits depuis 1900
An 2038 (Y2K38)2038-01-19Secondes signées sur 32 bits depuis 1970
An 21062106-02-07Secondes non signées sur 32 bits depuis 1970

Références associées

FAQ

Qu'est-ce que le problème de l'an 2038 ?
Le problème de l'an 2038 (Y2K38) est un bug où les systèmes qui stockent les timestamps Unix dans des entiers signés 32 bits déborderont le 19 janvier 2038 à 03:14:07 UTC. La valeur maximale d'un entier signé 32 bits est 2 147 483 647. Une seconde plus tard, l'entier bascule vers -2 147 483 648, ce qui correspond au 13 décembre 1901.
Quel est le timestamp Unix du 19 janvier 2038 ?
Le timestamp Unix du 19 janvier 2038 à 03:14:07 UTC est 2 147 483 647 — la valeur maximale d'un entier signé 32 bits (2^31 - 1). C'est le moment exact où le dépassement de l'an 2038 survient sur les systèmes 32 bits.
Comment corriger le problème de l'an 2038 ?
Stockez le temps dans un entier signé 64 bits au lieu de 32 bits. Utilisez un time_t 64 bits (compilez le code 32 bits avec -D_TIME_BITS=64 sur glibc 2.34+), BIGINT au lieu de INT pour les colonnes epoch, et DATETIME au lieu de MySQL TIMESTAMP. Une valeur de temps signée 64 bits ne déborde pas avant environ 292 milliards d'années.
Y2K38 est-il la même chose que Y2K ?
Non. Y2K (problème de l'an 2000) venait du stockage des années sur deux chiffres. Y2K38 vient du stockage des timestamps Unix dans des entiers signés 32 bits qui débordent en 2038. Causes différentes, systèmes touchés différents.
Qu'est-ce que le problème de l'an 2106 ?
L'an 2106 est le même dépassement pour les timestamps non signés 32 bits, qui arrivent à court le 7 février 2106 à 06:28:15 UTC. Passer de signé à non signé 32 bits gagne 68 ans de plus, mais ce n'est pas une vraie solution ; le temps 64 bits l'est.
Internet va-t-il s'effondrer en 2038 ?
Probablement pas de façon notable. La majeure partie de l'infrastructure internet a déjà migré vers des systèmes 64 bits. Le risque se concentre sur les systèmes embarqués, les anciens objets connectés et les logiciels non mis à jour depuis des décennies. Les systèmes d'exploitation, langages et bases de données modernes sont déjà sûrs.