El problema del año 2038 (también conocido como Y2038 , [1] Y2K38 , superbug Y2K38 o Epocalipsis [2] [3] ) es un problema de cálculo del tiempo que deja a algunos sistemas informáticos incapaces de representar horas posteriores a las 03:14:07 UTC del 19 de enero de 2038.
El problema existe en sistemas que miden el tiempo Unix (el número de segundos transcurridos desde la época Unix (00:00:00 UTC del 1 de enero de 1970)) y lo almacenan en un entero con signo de 32 bits . El tipo de datos solo es capaz de representar números enteros entre −(2 31 ) y 2 31 − 1 , lo que significa que el último tiempo que se puede codificar correctamente es 2 31 − 1 segundos después de la época (03:14:07 UTC del 19 de enero de 2038). Intentar incrementar al segundo siguiente (03:14:08) hará que el entero se desborde , estableciendo su valor en −(2 31 ) que los sistemas interpretarán como 2 31 segundos antes de la época (20:45:52 UTC del 13 de diciembre de 1901). El problema es de naturaleza similar al problema del año 2000 , con la diferencia de que el problema del año 2000 tenía que ver con números de base 10 , mientras que el problema del año 2038 involucra números de base 2 .
Se alcanzarán restricciones de almacenamiento análogas en 2106 , donde los sistemas que almacenan la hora Unix como un entero de 32 bits sin signo (en lugar de con signo) se desbordarán el 7 de febrero de 2106 a las 06:28:15 UTC.
Los sistemas informáticos que utilizan el tiempo para cálculos críticos pueden encontrar errores fatales si no se soluciona el problema del año 2038. Algunas aplicaciones que utilizan fechas futuras ya han encontrado el error. [4] [5] Los sistemas más vulnerables son aquellos que se actualizan con poca frecuencia o nunca, como los sistemas heredados y embebidos . Los sistemas modernos y las actualizaciones de software de los sistemas heredados solucionan este problema utilizando números enteros con signo de 64 bits en lugar de números enteros de 32 bits, que tardarán 292 mil millones de años en desbordarse, aproximadamente 21 veces la edad estimada del universo .
Muchos sistemas informáticos miden la hora y la fecha utilizando el tiempo Unix , un estándar internacional para el cronometraje digital. El tiempo Unix se define como el número de segundos transcurridos desde las 00:00:00 UTC del 1 de enero de 1970 (un tiempo elegido arbitrariamente en función de la creación del primer sistema Unix ), que se ha denominado la época Unix . [6]
Históricamente, el tiempo Unix se ha codificado como un entero con signo de 32 bits , un tipo de datos compuesto por 32 dígitos binarios (bits) que representan un valor entero, donde "con signo" significa que el número puede representar números positivos y negativos, así como el cero; y generalmente se almacena en formato de complemento a dos . [a] Por lo tanto, un entero con signo de 32 bits solo puede representar valores enteros de −(2 31 ) a 2 31 − 1 inclusive. En consecuencia, si se utiliza un entero de 32 bits con signo para almacenar la hora Unix, la última hora que se puede almacenar es 2 31 − 1 (2.147.483.647) segundos después de epoch, que es 03:14:07 del martes 19 de enero de 2038. [7] Los sistemas que intenten incrementar este valor en un segundo más hasta 2 31 segundos después de epoch (03:14:08) sufrirán un desbordamiento de entero , invirtiendo inadvertidamente el bit de signo para indicar un número negativo. Esto cambia el valor entero a −(2 31 ), o 2 31 segundos antes de epoch en lugar de después , que los sistemas interpretarán como 20:45:52 del viernes 13 de diciembre de 1901. A partir de aquí, los sistemas seguirán contando hacia arriba, hacia cero, y luego hacia arriba a través de los enteros positivos nuevamente. Como muchos sistemas informáticos utilizan cálculos de tiempo para ejecutar funciones críticas, el error puede introducir problemas graves.
Cualquier sistema que utilice estructuras de datos con representaciones de tiempo de 32 bits con signo tiene un riesgo inherente de fallar. Es prácticamente imposible obtener una lista completa de estas estructuras de datos, pero existen estructuras de datos bien conocidas que presentan el problema de tiempo de Unix:
UNIX_TIMESTAMP()
comandos similaresLos sistemas integrados que utilizan fechas para el cálculo o el registro de diagnóstico son los más propensos a verse afectados por el problema Y2038. [1] A pesar de la actualización generacional moderna de 18 a 24 meses en la tecnología de sistemas informáticos , los sistemas integrados están diseñados para durar toda la vida útil de la máquina en la que son un componente. Es concebible que algunos de estos sistemas todavía puedan estar en uso en 2038. Puede resultar poco práctico o, en algunos casos, imposible actualizar el software que ejecuta estos sistemas, lo que en última instancia requerirá su reemplazo si se quieren corregir las limitaciones de 32 bits.
Muchos sistemas de transporte, desde los aviones hasta los automóviles, utilizan ampliamente sistemas integrados. En los sistemas automotrices, esto puede incluir el sistema de frenos antibloqueo (ABS), el control electrónico de estabilidad (ESC/ESP), el control de tracción (TCS) y la tracción a las cuatro ruedas automática ; las aeronaves pueden utilizar sistemas de guía inercial y receptores GPS . [b] Otro uso importante de los sistemas integrados es en los dispositivos de comunicaciones, incluidos los teléfonos celulares y los dispositivos habilitados para Internet (por ejemplo, enrutadores , puntos de acceso inalámbricos , cámaras IP ) que dependen del almacenamiento de una hora y fecha precisas y se basan cada vez más en sistemas operativos tipo Unix. Por ejemplo, el problema Y2038 hace que algunos dispositivos que ejecutan Android de 32 bits se bloqueen y no se reinicien cuando se cambia la hora a esa fecha. [8]
Sin embargo, esto no implica que todos los sistemas integrados sufrirán el problema Y2038, ya que muchos de estos sistemas no requieren acceso a fechas. En el caso de los que sí lo requieren, aquellos sistemas que solo rastrean la diferencia entre horas/fechas y no horas/fechas absolutas, por la naturaleza del cálculo, no experimentarán un problema importante. Este es el caso de los diagnósticos automotrices basados en estándares legislados como CARB ( California Air Resources Board ). [9]
En mayo de 2006, aparecieron informes de una manifestación temprana del problema Y2038 en el software AOLserver . El software fue diseñado con un truco para manejar una solicitud de base de datos que "nunca" debería caducar. En lugar de manejar específicamente este caso especial, el diseño inicial simplemente especificó una fecha de caducidad arbitraria en el futuro con una configuración predeterminada que especificaba que las solicitudes deberían caducar después de un máximo de mil millones de segundos. Sin embargo, mil millones de segundos antes de la fecha límite de 2038 son las 01:27:28 UTC del 13 de mayo de 2006, por lo que las solicitudes enviadas después de esta hora darían como resultado una fecha de caducidad que está más allá de la fecha límite. Esto hizo que los cálculos de caducidad se desbordaran y devolvieran fechas que en realidad estaban en el pasado, lo que provocó que el software fallara. Cuando se descubrió el problema, los operadores de AOLServer tuvieron que editar el archivo de configuración y establecer el tiempo de caducidad en un valor menor. [4] [5]
No existe una solución universal para el problema del año 2038. Por ejemplo, en el lenguaje C , cualquier cambio en la definición del time_t
tipo de datos generaría problemas de compatibilidad de código en cualquier aplicación en la que las representaciones de fecha y hora dependan de la naturaleza del time_t
entero de 32 bits con signo. Por ejemplo, cambiar time_t
a un entero de 32 bits sin signo, lo que ampliaría el rango hasta 2106 [10] (específicamente, las 06:28:15 UTC del domingo 7 de febrero de 2106), afectaría negativamente a los programas que almacenan, recuperan o manipulan fechas anteriores a 1970, ya que dichas fechas se representan con números negativos. Aumentar el tamaño del time_t
tipo a 64 bits en un sistema existente provocaría cambios incompatibles en el diseño de las estructuras y la interfaz binaria de las funciones.
La mayoría de los sistemas operativos diseñados para funcionar en hardwaretime_t
de 64 bits ya utilizan números enteros de 64 bits con signo . El uso de un valor de 64 bits con signo introduce una nueva fecha de cierre que es más de veinte veces mayor que la edad estimada del universo : aproximadamente 292 mil millones de años a partir de ahora. [11] La capacidad de realizar cálculos sobre fechas está limitada por el hecho de que tm_year
se utiliza un valor entero de 32 bits con signo que comienza en 1900 para el año. Esto limita el año a un máximo de 2.147.485.547 (2.147.483.647 + 1900). [12]
Se han hecho propuestas alternativas (algunas de las cuales ya están en uso), como almacenar milisegundos o microsegundos desde una época (normalmente el 1 de enero de 1970 o el 1 de enero de 2000) en un entero con signo de 64 bits, proporcionando un rango mínimo de 292.000 años con una resolución de microsegundos. [13] [14] En particular, el uso de enteros con signo de 64 bits de Java y JavaScript para representar marcas de tiempo absolutas como "milisegundos desde el 1 de enero de 1970" funcionará correctamente durante los próximos 292 millones de años . Otras propuestas para nuevas representaciones de tiempo proporcionan diferentes precisiones, rangos y tamaños (casi siempre más amplios que 32 bits), además de resolver otros problemas relacionados, como el manejo de segundos intercalares . En particular, TAI64 [15] es una implementación del estándar de Tiempo Atómico Internacional (TAI), el estándar internacional actual en tiempo real para definir un segundo y un marco de referencia.
time_t
. [17]time_t
tanto para arquitecturas de 32 bits como de 64 bits. Las aplicaciones compiladas para una versión anterior de NetBSD con 32 bits time_t
son compatibles a través de una capa de compatibilidad binaria, pero dichas aplicaciones antiguas seguirán sufriendo el problema Y2038. [18]time_t
para arquitecturas de 32 y 64 bits. A diferencia de NetBSD , no existe una capa de compatibilidad binaria. Por lo tanto, las aplicaciones que esperan 32 bits time_t
y las aplicaciones que utilizan algo diferente a time_t
para almacenar valores de tiempo pueden fallar. [19]time_t
solo para arquitecturas de 64 bits; la ABI pura de 32 bits no se modificó debido a la compatibilidad con versiones anteriores. [20] A partir de la versión 5.6 de 2020, los 64 bits time_t
también son compatibles con arquitecturas de 32 bits. Esto se hizo principalmente por el bien de los sistemas Linux integrados . [21]time_t
en plataformas de 32 bits con versiones de Linux adecuadas. Esta compatibilidad se puede activar definiendo una macro de preprocesador _TIME_BITS
al 64
compilar el código fuente. [22]time_t
para todas las arquitecturas de 32 y 64 bits excepto i386 de 32 bits, que utiliza 32 bits con signo time_t
en su lugar. [23]time_t
. Como era un entorno nuevo, no era necesario tomar precauciones especiales de compatibilidad. [20]struct nfstime4 {int64_t seconds; uint32_t nseconds;}
desde diciembre de 2000. [24] La versión 3 admite valores de 32 bits sin signo como struct nfstime3 {uint32 seconds; uint32 nseconds;};
. [25] Los valores mayores que cero para el campo de segundos denotan fechas posteriores a la hora 0, el 1 de enero de 1970. Los valores menores que cero para el campo de segundos denotan fechas anteriores a la hora 0, el 1 de enero de 1970. En ambos casos, el campo nsegundos (nanosegundos) se debe agregar al campo de segundos para la representación de tiempo final.time_t
. [29] Como parte del trabajo de cumplimiento de Y2K que se llevó a cabo en 1998, la CRTL se modificó para utilizar números enteros de 32 bits sin signo para representar el tiempo; extendiendo el rango time_t
hasta el 7 de febrero de 2106. [30]FROM_UNIXTIME()
, UNIX_TIMESTAMP()
y CONVERT_TZ()
manejan valores de 64 bits en plataformas que las admiten. Esto incluye versiones de 64 bits de Linux, macOS y Windows. [32] [33] En versiones anteriores, las funciones integradas como UNIX_TIMESTAMP()
devolverán 0 después de las 03:14:07 UTC del 19 de enero de 2038. [34]TIMESTAMP
y las funciones FROM_UNIXTIME()
, UNIX_TIMESTAMP()
y CONVERT_TZ()
manejan valores de 32 bits sin signo en versiones de 64 bits de Linux, macOS y Windows. [35] Esto extendió el rango a 2106-02-07 06:28:15 y permitió a los usuarios almacenar dichos valores de marca de tiempo en tablas sin cambiar el diseño de almacenamiento y, por lo tanto, permanecer totalmente compatibles con los datos de usuario existentes.time_t
la macro del preprocesador. [36] Sin embargo, la API de Windows en sí no se ve afectada por el error del año 2038, ya que Windows rastrea internamente el tiempo como el número de intervalos de 100 nanosegundos desde el 1 de enero de 1601 en un entero con signo de 64 bits, que no se desbordará hasta el año 30.828 . [37]_USE_32BIT_TIME_T