Error del año 2038: ¿Qué es? ¿Cómo resolverlo?
Estaba pensando en usar TIMESTAMP para almacenar la fecha y la hora, pero leí que existe una limitación del año 2038. En lugar de hacer mi pregunta de forma masiva, preferí dividirla en partes pequeñas para que también sea fácil de entender para los usuarios novatos. Entonces mi(s) pregunta(s):
- ¿Qué es exactamente el problema del año 2038?
- ¿Por qué ocurre y qué sucede cuando ocurre?
- ¿Como lo resolvemos?
- ¿Existen posibles alternativas a su uso que no planteen un problema similar?
- ¿Qué podemos hacer con las aplicaciones existentes que utilizan TIMESTAMP para evitar el llamado problema, cuando realmente ocurre?
He marcado esto como un wiki comunitario, así que siéntete libre de editarlo cuando quieras.
¿Qué es exactamente el problema del año 2038?
"El problema del año 2038 (también conocido como Unix Millennium Bug, Y2K38 por analogía con el problema Y2K) puede provocar que algunos programas informáticos fallen antes o en el año 2038. El problema afecta a todos los programas y sistemas que almacenan la hora del sistema como un 32 firmado -bit entero e interpretar este número como el número de segundos desde las 00:00:00 UTC del 1 de enero de 1970."
¿Por qué ocurre y qué sucede cuando ocurre?
Las horas posteriores a las 03:14:07 UTC del martes 19 de enero de 2038 se "volverán" y se almacenarán internamente como un número negativo, que estos sistemas interpretarán como una hora del 13 de diciembre de 1901 en lugar de 2038. Esto se debe a el hecho de que el número de segundos desde la época UNIX (1 de enero de 1970 00:00:00 GMT) habrá excedido el valor máximo de una computadora para un entero de 32 bits con signo.
¿Como lo resolvemos?
- Utilice tipos de datos largos (64 bits son suficientes)
- Para MySQL (o MariaDB), si no necesita la información de tiempo, considere usar el
DATE
tipo de columna. Si necesita mayor precisión, utiliceDATETIME
en lugar deTIMESTAMP
. Tenga en cuenta queDATETIME
las columnas no almacenan información sobre la zona horaria, por lo que su aplicación tendrá que saber qué zona horaria se utilizó. - Otras posibles soluciones descritas en Wikipedia
- Actualice su Mysql a 8.0.28 o superior
¿Existen posibles alternativas a su uso que no planteen un problema similar?
Intente utilizar siempre que sea posible tipos grandes para almacenar fechas en bases de datos: 64 bits es suficiente: un tipo largo en GNU C y POSIX/SuS, o sprintf('%u'...)
en PHP o la extensión BCmath.
¿Cuáles son algunos casos de uso potencialmente disruptivos aunque todavía no estemos en 2038?
Entonces, MySQL DATETIME tiene un rango de 1000-9999, pero TIMESTAMP solo tiene un rango de 1970-2038. Si su sistema almacena fechas de nacimiento, fechas futuras (por ejemplo, hipotecas a 30 años) o similares, ya se encontrará con este error. Nuevamente, no use TIMESTAMP si esto va a ser un problema.
¿Qué podemos hacer con las aplicaciones existentes que utilizan TIMESTAMP para evitar el llamado problema, cuando realmente ocurre?
Pocas aplicaciones PHP seguirán existiendo en 2038, aunque es difícil preverlo, ya que la web aún no es una plataforma heredada.
A continuación se muestra un proceso para modificar una columna de una tabla de base de datos para convertirla TIMESTAMP
a DATETIME
. Comienza con la creación de una columna temporal:
# rename the old TIMESTAMP field
ALTER TABLE `myTable` CHANGE `myTimestamp` `temp_myTimestamp` int(11) NOT NULL;
# create a new DATETIME column of the same name as your old column
ALTER TABLE `myTable` ADD `myTimestamp` DATETIME NOT NULL;
# update all rows by populating your new DATETIME field
UPDATE `myTable` SET `myTimestamp` = FROM_UNIXTIME(temp_myTimestamp);
# remove the temporary column
ALTER TABLE `myTable` DROP `temp_myTimestamp`
Recursos
- Problema del año 2038 (Wikipedia)
- Internet terminará en 30 años
Cuando se utilizan marcas de tiempo UNIX para almacenar fechas, en realidad se utilizan números enteros de 32 bits, que mantienen la cuenta del número de segundos desde 1970-01-01; ver tiempo Unix
Ese número de 32 bits se desbordará en 2038. Ese es el problema de 2038.
Para resolver ese problema, no debe usar una marca de tiempo UNIX de 32 bits para almacenar sus fechas, lo que significa que, cuando use MySQL, no debe usar TIMESTAMP
, sino DATETIME
(consulte 10.3.1. Tipos DATETIME, DATE y TIMESTAMP ):
El
DATETIME
tipo se utiliza cuando necesita valores que contengan información de fecha y hora. El rango admitido es'1000-01-01 00:00:00'
de'9999-12-31 23:59:59'
.El
TIMESTAMP
tipo de datos tiene un rango de'1970-01-01 00:00:01'
UTC a'2038-01-19 03:14:07'
UTC.
Lo (probablemente) mejor que puede hacerle a su aplicación para evitar/solucionar ese problema es no usar TIMESTAMP
, pero DATETIME
las columnas que deben contener fechas que no estén entre 1970 y 2038.
Sin embargo, una pequeña nota: existe una probabilidad muy alta (estadísticamente hablando) de que su aplicación haya sido reescrita un par de veces antes de 2038 ^^ Entonces, tal vez, si no tiene que lidiar con fechas en el futuro. , no tendrás que solucionar ese problema con la versión actual de tu aplicación...
Una búsqueda rápida en Google solucionará el problema: el problema del año 2038
- El problema del año 2038 (también conocido como Unix Millennium Bug, Y2K38 por analogía con el problema Y2K) puede provocar que algunos programas informáticos fallen antes o en el año 2038.
- El problema afecta a todo el software y los sistemas que almacenan la hora del sistema como un entero de 32 bits con signo e interpretan este número como el número de segundos desde las 00:00:00 UTC del 1 de enero de 1970. La última hora que se puede representar de esta manera son las 03:14:07 UTC del martes 19 de enero de 2038. Los tiempos posteriores a este momento "volverán" y se almacenarán internamente como un número negativo, que estos sistemas interpretarán como una fecha de 1901 en lugar de 2038.
- No existe una solución fácil para este problema para las combinaciones de CPU/OS existentes, sistemas de archivos existentes o formatos de datos binarios existentes.