Year 2038 Problem

El problema del año 2038 (Y2K38) explicado

El 19 de enero de 2038 a las 03:14:07 UTC, el timestamp Unix 2 147 483 647 — el valor máximo de un entero con signo de 32 bits — desbordará y saltará a una fecha de 1901. Aquí tienes qué significa, qué sistemas se ven afectados, cómo funciona la corrección con time_t de 64 bits y cómo probar tu propio código.

El desbordamiento en una línea

Un entero con signo de 32 bits llega como máximo a 2 147 483 647. Almacenado como segundos Unix, ese valor es el 19/01/2038 03:14:07 UTC — y un segundo después salta a -2 147 483 648, que se lee como 13 de diciembre de 1901. Cualquier sistema que aún guarde el tiempo en un entero con signo de 32 bits dará un salto de 137 años al pasado en ese instante. La corrección cabe en una palabra: 64 bits. La tabla siguiente muestra qué tipos de almacenamiento se ven afectados y cuáles ya son seguros.

Tipo de almacenamientoDesborda en / fecha máx.¿Seguro tras 2038?
time_t con signo 32 bits / SQL INT2038-01-19 03:14:07 UTCNo
MySQL TIMESTAMP2038-01-19 03:14:07 UTCNo — usar DATETIME
32 bits sin signo2106-02-07 06:28:15 UTCGana 68 años, no es una solución
time_t con signo 64 bits / SQL BIGINT~292 000 millones de años
Flotante de 64 bits (JavaScript, Python)año 275 760
MySQL DATETIME (campos empaquetados)año 9999

¿Qué es el problema del año 2038?

Los timestamps Unix se almacenan tradicionalmente en un entero con signo de 32 bits que cuenta los segundos desde el 1 de enero de 1970 00:00:00 UTC. El valor máximo de un entero con signo de 32 bits es 2 147 483 647 — que corresponde al 19 de enero de 2038 a las 03:14:07 UTC. Un segundo después de ese momento, el entero desborda a -2 147 483 648. Interpretado como timestamp Unix, ese valor negativo corresponde al 13 de diciembre de 1901 — enviando los sistemas afectados casi 137 años al pasado.

  • 2^31 − 1 = 2 147 483 647 (entero con signo de 32 bits máximo)
  • 2 147 483 647 como fecha = 19 de enero de 2038 03:14:07 UTC
  • 2 147 483 647 + 1 desborda a −2 147 483 648 (el valor de 32 bits más negativo)
  • −2 147 483 648 como fecha = 13 de diciembre de 1901 20:45:52 UTC
  • La hora local del desbordamiento varía: 22:14:07 EST el 18 de enero, 14:14:07 JST el 19 de enero

¿Qué sistemas corren riesgo?

El problema afecta a los sistemas que almacenan timestamps como enteros con signo de 32 bits:

  • Sistemas embebidos y microcontroladores con time_t de 32 bits
  • Código C y C++ antiguo compilado para objetivos de 32 bits que usa time_t o int para timestamps
  • Núcleos Linux antiguos (anteriores a 5.6) en hardware de 32 bits aún en producción
  • Columnas MySQL TIMESTAMP — limitadas al 2038-01-19; usar DATETIME en su lugar
  • Algunos protocolos de red y formatos de archivo que codifican timestamps como valores de 32 bits
  • Firmware en sistemas de control industrial y dispositivos IoT con vidas útiles de décadas

¿Qué sistemas son seguros?

La mayor parte del código y la infraestructura modernos ya no se ven afectados:

  • Cualquier SO de 64 bits — Linux (glibc 2.34+ también corrige el hardware de 32 bits), macOS, Windows
  • Python — los timestamps usan flotantes de 64 bits, seguros mucho más allá del año 292 millones
  • JavaScript — Date usa flotantes IEEE 754 de 64 bits, seguro hasta el año 275 760
  • Go y Rust — usan int64 para el tiempo internamente, seguros durante miles de millones de años
  • Java — java.time.Instant usa long (64 bits), seguro hasta el año ~292 millones
  • PostgreSQL TIMESTAMP — almacena fechas más allá de 2038 correctamente
  • MySQL DATETIME — rango 1000-01-01 a 9999-12-31, no afectado

MySQL TIMESTAMP y el techo de 2038

MySQL tiene dos tipos principales de columna fecha-hora que se comportan muy distinto en torno a 2038:

  • TIMESTAMP se almacena internamente como un entero Unix con signo de 32 bits — desborda el 2038-01-19 03:14:07 UTC
  • DATETIME se almacena como campos A/M/D h/m/s empaquetados y admite hasta el año 9999 — úsalo para cualquier fecha que pueda ser posterior a 2038
  • TIMESTAMP también convierte implícitamente desde/hacia la zona de sesión del servidor; DATETIME almacena el valor tal cual
  • Para columnas epoch en bruto, almacena BIGINT en lugar de INT para que el valor en sí no pueda desbordar
  • Audita los esquemas existentes: SELECT TABLE_NAME, COLUMN_NAME FROM information_schema.COLUMNS WHERE DATA_TYPE = "timestamp"

Linux embebido y time_t de 32 bits

El mayor riesgo Y2038 que queda está en sistemas embebidos de larga vida: routers, controladores industriales, centralitas de automoción, contadores inteligentes y dispositivos IoT que se enviaron con núcleos de 32 bits y pueden seguir en servicio después de 2038. Tanto la biblioteca C como cualquier protocolo binario propio deben estar limpios en 64 bits.

  • glibc obtuvo time_t de 64 bits para ABI de 32 bits mediante la macro de compilación -D_TIME_BITS=64 (glibc 2.34+)
  • musl libc usa time_t de 64 bits por defecto desde la versión 1.2.0 (2020)
  • Debian, Ubuntu y OpenWrt han migrado todos sus ports de 32 bits a time_t de 64 bits
  • Los timestamps del sistema de archivos son un asunto aparte: ext2/ext3 usan tiempos de 32 bits; ext4 admite 64 bits en inodos ≥ 256 bytes
  • Para hardware que aún se envíe en 2026+, confirma que tanto la biblioteca C como cualquier formato de cable sean de 64 bits

Cómo corregir y probar para Y2038

La corrección siempre es la misma — ampliar el tiempo a 64 bits — pero hay que aplicarla en cada capa que almacena o transmite un timestamp: la biblioteca C, las columnas de la base de datos y cualquier protocolo binario o formato de archivo. La forma más rápida de encontrar un problema es mover un reloj más allá del límite en un entorno de pruebas y vigilar las fechas que aterrizan en 1901.

  • Compila el código de 32 bits con -D_TIME_BITS=64 (y -D_FILE_OFFSET_BITS=64) en glibc 2.34+
  • Usa BIGINT, no INT, para cualquier columna que almacene segundos o milisegundos Unix en bruto
  • Prefiere DATETIME o TIMESTAMPTZ frente a MySQL TIMESTAMP para fechas que puedan superar 2038
  • En pruebas, pon el reloj del sistema o del contenedor en 2038-01-19T03:14:08Z y comprueba que las fechas se quedan en 2038
  • Revisa los formatos de cable y las cabeceras de archivo — un SO de 64 bits no ayuda si el campo del protocolo es de 32 bits

Reinicios relacionados: Y2K, GPS, NTP y 2106

El año 2038 es uno de una familia de reinicios cíclicos de ancho fijo. Cada uno viene de meter un reloj en demasiado pocos bits, y conocer las fechas ayuda a detectar el siguiente antes de que se despliegue:

ReinicioFechaCausa
Y2K2000-01-01Almacenamiento del año con dos dígitos
Reinicio de semana GPS2019-04-06Contador de semana GPS de 10 bits
Reinicio de era NTP2036-02-07Segundos sin signo de 32 bits desde 1900
Año 2038 (Y2K38)2038-01-19Segundos con signo de 32 bits desde 1970
Año 21062106-02-07Segundos sin signo de 32 bits desde 1970

Referencias relacionadas

FAQ

¿Qué es el problema del año 2038?
El problema del año 2038 (Y2K38) es un fallo en el que los sistemas que almacenan timestamps Unix en enteros con signo de 32 bits desbordarán el 19 de enero de 2038 a las 03:14:07 UTC. El valor máximo de un entero con signo de 32 bits es 2 147 483 647. Un segundo después, el entero salta a -2 147 483 648, que corresponde al 13 de diciembre de 1901.
¿Cuál es el timestamp Unix del 19 de enero de 2038?
El timestamp Unix del 19 de enero de 2038 a las 03:14:07 UTC es 2 147 483 647 — el valor máximo de un entero con signo de 32 bits (2^31 - 1). Es el momento exacto en que ocurre el desbordamiento del año 2038 en los sistemas de 32 bits.
¿Cómo corrijo el problema del año 2038?
Almacena el tiempo en un entero con signo de 64 bits en lugar de 32 bits. Usa time_t de 64 bits (compila el código de 32 bits con -D_TIME_BITS=64 en glibc 2.34+), BIGINT en lugar de INT para columnas epoch, y DATETIME en lugar de MySQL TIMESTAMP. Un valor de tiempo con signo de 64 bits no desborda hasta dentro de unos 292 000 millones de años.
¿Y2K38 es lo mismo que Y2K?
No. Y2K (problema del año 2000) se debía a que los programas almacenaban los años con dos dígitos. Y2K38 se debe a almacenar timestamps Unix como enteros con signo de 32 bits que desbordan en 2038. Causas distintas, sistemas afectados distintos.
¿Qué es el problema del año 2106?
El año 2106 es el mismo desbordamiento para los timestamps sin signo de 32 bits, que se agotan el 7 de febrero de 2106 a las 06:28:15 UTC. Pasar de con signo a sin signo de 32 bits gana 68 años más, pero no es una solución real; el tiempo de 64 bits sí lo es.
¿Se vendrá abajo internet en 2038?
Probablemente no de forma significativa. La mayor parte de la infraestructura de internet ya ha migrado a sistemas de 64 bits. El riesgo se concentra en sistemas embebidos, dispositivos IoT antiguos y software que lleva décadas sin actualizarse. Los sistemas operativos, lenguajes y bases de datos modernos ya son seguros.