# Problema del año 2038

En informática, el problema del año 2038 (conocido también por el numerónimo Y2K38) amenaza que podría causar que una gran parte del software falle en ese año. El problema afecta mucho a los programas que usen la representación del tiempo basada en el sistema POSIX (Tiempo Unix), que se basa en contar el número de segundos transcurridos desde la noche del 1 de enero de 1970 a las 00:00:00 (ignorando los segundos intercalares).
Esta representación es un estándar de facto en los sistemas tipo Unix y también en los programas escritos para muchos otros sistemas operativos debido al gran alcance del lenguaje de programación C. En la mayoría de sistemas de 32 bits, el tipo de dato time_t usado para guardar el contador de segundos es un entero de 32 bits con signo, es decir, que puede representar un rango de números entre -2 147 483 648 y 2 147 483 647 (-2$^{31}$ y 2$^{31}$-1; 1 bit para el signo, y 31 para representar su valor en complemento a dos), por lo que el último segundo representable con este formato será a las 03:14:07 UTC del 19 de enero de 2038, cuando el contador llegue a 2 147 483 647. Un segundo después, el contador se desbordará y saltará al valor -2 147 483 648, que causará el gran fallo de programas que interpretarán el tiempo como que están en 1901 (dependiendo de la implementación), en vez de en 2038. A su vez, esto causaría cálculo y procesamiento incorrecto y causaría un gran problema mundial.
No hay una forma sencilla de arreglar este problema para las combinaciones existentes de CPU/SO. Cambiar la definición de time_t para usar un tipo de 64 bits rompería una gran parte de la compatibilidad binaria para el software, almacenamiento de datos y, por lo general, cualquier cosa que tenga algo que ver con la representación binaria del tiempo. Cambiar time_t a un entero de 32 bits sin signo afectaría a los programas que hacen cálculos con diferencias de tiempo.
La mayoría de sistemas operativos para arquitecturas de 64 bits utilizan enteros de 64 bits para time_t. La migración a estos sistemas está todavía en proceso y se espera que se complete mucho antes de 2038. Usar un entero de 64 bits retrasaría la fecha del problema a unos 292 mil millones de años (2,9 × 10$^{11}$). Es decir, 22 veces la edad aproximada del universo.

## Antecedentes

* Muy relacionado con el tema del año 2038 está el año 2036 (numérico: Y2K36). El 7 de febrero de 2036 a las 06:28:16 UTC, el contador del protocolo de sincronización de hora NTP (Protocolo de tiempo de red), ampliamente utilizados en los círculos de Unix, llegará a su máximo valor en muchos dispositivos, especialmente los sistemas integrados, que todavía utilizan el antiguo estándar RFC 868. En las implementaciones modernas, este problema está resuelto en la RFC 5905. En este caso el contexto es que el tiempo de espera se lleva a cabo con un número de 32 bits en segundos, pero sin signo y con la hora de inicio del 1 de enero de 1900 a las 00:00:00 UTC. Con una implementación muy adecuada de los sistemas, no hay mayor problema durante el cálculo, ya que la sincronización de tiempo debería funcionar de acuerdo con un método de diferencia. Si un cliente no conoce la hora actual (inicio en frío en sistemas sin reloj de hardware) y no verifica una fecha mínima (por ejemplo, la fecha de su compilación o la fecha del software NTP), podría probar la fecha 1900-01-01 UTC, que no se puede mostrar en tiempo de Unix y entonces el reloj interno del sistema afectado puede saltar a valores "absurdos", lo que puede conducir a un fallo total.
* El Boeing 787 presenta una falla de software que obliga a apagar cada cierto tiempo —y por completo— los sistemas eléctricos a fin de prevenir entrar en modo de fallo, lo que ocasionaría el apagado de los motores en vuelo. La remota posibilidad ocurre en un software contador de centésimas de segundos que se desborda después de poco más de 248 días de funcionamiento continuo (248×24 horas ×3600 segundos ×100 = 2 142 720 000). La Administración Federal de Aviación (FAA) consideró menos peligroso y económico el implementar una directiva de aeronavegabilidad contra sustituir el software de todos los aviones a nivel mundial.
* Algunos modelos de unidades de estado sólido vendidos por la empresa Hewlett Packard Enterprise fueron implementados con un contador de horas mientras está encendido. Dicho valor se guardaba en una variable de 2 bytes con signo por lo que al alcanzar las 32 768 horas de uso (2$^{15}$) los datos almacenados solo pudieron ser recuperados mediante una actualización de firmware.
* El 8 de agosto de 2013 la sonda espacial Deep Impact tuvo una falla en el conteo del tiempo, lo que ocasionó la mala orientación de sus paneles solares quedando así sin suministro eléctrico para comunicarse y condujo a la finalización de la misión. En este caso el conteo se llevaba a cabo por décimas de segundo en una variable de 32 bits sin signo: 2$^{32}$=4 294 967 296; si sumamos 4 294 967 296 décimas de segundo a la fecha 1 de enero de 2000 resulta 11 de agosto de 2013 12:38:49 a. m., teniendo en cuenta, además, el fenómeno de la dilatación del tiempo.
* De manera similar algunos dispositivos de Sistema de Posicionamiento Global llevan cuenta del tiempo por semanas en un campo de 10 bits (a partir del 6 de enero de 1980), permitiendo un máximo de 1024 semanas (2$^{10}$). El primer reinicio ocurrió el 21 de agosto de 1999 (en inglés: GPS Time Epoch), y el segundo el 6 de abril de 2019, abriendo la posibilidad de que algunos artefactos tomen como fecha errónea el 5 de enero de 1980. Esto, básicamente, es el mismo problema de desborde de memoria numérica para el año 2038.

## Dispositivos afectados

El problema hacía que los dispositivos Android se bloquearan y no reiniciaran cuando se establecía la fecha límite. Para comprobar esto se puede ir a la configuración de fecha y hora en el dispositivo, y al tratar de cambiar la fecha y hora al 2038; se encontrará con la sorpresa de que solo le permite cambiarlo hasta el 31 de diciembre de 2037. En la versión 4.0.4 se agregó esta característica, en las versiones anteriores, el calendario mostraba fechas hasta 2104, pero al seleccionar una fecha más adelantada a la fecha límite, el calendario volvía a la fecha actual. El selector de fechas mostraba correctamente los años a simple vista, pero al poner un dedo sobre alguna fecha no contable, este marcaba su negativa, es decir, el 19 de enero de 2040 por ejemplo, a simple vista se veía correcto, pero el sistema marcaba 13 de diciembre de 1903, ya que al reiniciarse, la primera fecha mostrable es 13 de diciembre de 1901. Un dato curioso es que de esta forma el sistema no se tildaba ni reiniciaba, la única manera era dejando que el contador llegara al límite por sí mismo.
En los dispositivos iOS el sistema permite cambiar la fecha hasta el 1 de enero de 2038; sin embargo, desde el iPhone 5s en adelante se solucionaría, ya que estos modelos recientes de iPhone poseen un procesador de 64 bits que lo deja fuera de este problema. Igualmente Android ya está disponible en variantes de 64 bits desde la versión 5.0 por lo que gradualmente dejará atrás este problema. Los dispositivos con Android de 32 bits, Ubuntu Phone, Ubuntu Touch o Firefox OS llegan hasta el 31 de diciembre de 2037. Los dispositivos con Windows Phone 7 permiten llegar hasta el 1 de enero de 2040. Los dispositivos Windows Phone 8 no están afectados, y cuentan fechas desde el año 1601 hasta el 3000, concretamente el 1 de enero, al llegar a las 23:59, el contador regresa 24 horas y vuelve a marcar las 00:00 01/01/3000.
Concretamente, el problema afecta a los programas que usan la representación del tiempo basada en el sistema POSIX, que es el explicado en el párrafo anterior. Es la representación estándar en los sistemas tipo Unix y en todos los programas escritos en el lenguaje de programación C. La mayoría del software actual cae dentro de ese grupo y fallarán, dependiendo de como estén implementados, como si estuviesen funcionando en 1901 o 1970, en vez de en 2038. A pesar de ser un problema bien conocido (los programadores conocen esta limitación desde la implementación misma del lenguaje C), no existe una forma sencilla de solucionar este problema. Podría cambiarse el tipo de variable empleado por un entero de 32 bits sin signo, pero esto haría que todos los programas que hacen cálculos con diferencias de tiempo fallen. Y reescribir por completo esas aplicaciones es un trabajo enorme que solo puede evitarse migrando a los 64 bits.

## Soluciones actuales

La tecnología actual va dejando atrás gradualmente los 32 bits. Los mayores fabricantes de procesadores (Intel, AMD, Qualcomm, MediaTek y otros) ofrecen microprocesadores de 64 bits desde hace tiempo. También los desarrolladores de sistemas operativos han evolucionado hacia la plataforma de 64 bits:
* Microsoft ofrece versiones de Windows de 64 bits desde Windows XP, además la actual versión Windows 11 no cuenta con versiones de 32 bits.
* En macOS solo existen versiones en 64 bits desde Mac OS X 10.7
* En GNU/Linux existe en versiones de 64 bits desde el año 2003, Debian desde 2016 ha acelerado su desarrollo en procesadores de 64 bits.
* iOS usa 64 bits desde iOS 7.
* Android existe en versiones de 64 bits desde la versión 5.0.
De esta forma si hoy en día los 32 bits ya están siendo reemplazados, difícilmente seguirán en uso en 2038. Si todavía quedaran sistemas embebidos operando con 32 bits para aquel entonces, los fabricantes tendrían bastante tiempo para reparar el problema mediante actualizaciones.

### Solución para Kernel Linux

Resolver esta limitación de fecha en el sistema operativo Linux llevó a modificar todos los subsistemas e incluso más. Para resolverlo se echó mano de Espacio de usuario, la Biblioteca estándar de C, POSIX, y donde la tarea resultó ser más difícil fue en el campo del Sistema de archivos virtual debido al uso de estructuras de estampado de tiempo de 64 bits (struct timespec64) en los inodo. En junio de 2016 Linus Torvalds objetó uno de los cambios propuestos; para junio de 2018 se pudo agregar al kernel todos los cambios propuestos y el problema fue solucionado.