El Número Detras del Problema
2147483647 es 2^31 - 1, el valor máximo de un entero con signo de 32 bits. En binario:
01111111 11111111 11111111 11111111
El 0 inicial es el bit de signo. Cuándo los tiempos Unix se diseñaron a finales de los 1960s, almacenar el tiempo como un entero de 32 bits fue una elección pragmatica que equilibraba precisión, costo de almacenamiento y rango útil. Un entero con signo de 32 bits da aproximadamente 68 años de tiempo Unix positivo desde el 1 de enero de 1970.
Ese futuro es el 19 de enero de 2038 a las 03:14:07 UTC.
Que Ocurre en el Momento del Desbordamiento
Un segundo después de 2147483647, el contador con signo de 32 bits se desborda:
01111111 11111111 11111111 11111111 (2147483647)
+1
10000000 00000000 00000000 00000000 (-2147483648 en complemento a dos)
El patrón de bits 0x80000000 es -2147483648 cuando se interpreta como entero con signo. Cómo tiempo Unix, esto corresponde al 13 de diciembre de 1901 a las 20:45:52 UTC.
Comparación con Y2K
Y2K (Problema del Año 2000) surgio de representaciones de año de dos digitos (99 → 00). Y2K38 es estructuralmente similar pero más limitado:
- Y2K afecto a todo el software independientemente de la arquitectura. Y2K38 solo afecta a sistemas que usan time_t de 32 bits.
- Y2K se soluciono con un gran esfuerzo global en 1998-1999. La mitigación de Y2K38 ha estado en marcha desde los 1990s.
Sistemas Aún en Riesgo
Dispositivos embebidos e IoT
Muchos microcontroladores como ARM Cortex-M, MIPS y derivados antiguos de AVR funcionan en arquitecturas de 32 bits con firmware fijo.
Bases de datos antiguas
El tipo de datos TIMESTAMP de MySQL se almacena internamente como un tiempo Unix de 32 bits, con un valor máximo de 2038-01-19 03:14:07. El tipo DATETIME no tiene esta limitación.
-- Valor máximo de MySQL TIMESTAMP
SELECT FROM_UNIXTIME(2147483647);
-- Devuelve: 2038-01-19 03:14:07
-- DATETIME no tiene ese limite
ALTER TABLE events MODIFY created_at DATETIME(3);
Instalaciones Linux de 32 bits
Versiones antiguas del kernel 3.x en hardware de 32 bits sin soporte glibc 2.32+ para time_t de 64 bits.
Como Verificar tu Sistema
# Linux - verificar el tamaño de time_t
getconf TIME_BITS
# Salida: 32 o 64
# Verificar la fecha máxima de 32 bits
# Si esto no funciona, estas en 64 bits
date -d "@2147483647"
date -d "@2147483648"
# El segundo debería fallar o mostrar 1901