Mysql
 sql >> Database >  >> RDS >> Mysql

PHP e MySQL:bug dell'anno 2038:che cos'è? Come risolverlo?

Ho contrassegnato questo come wiki della community, quindi sentiti libero di modificare a tuo piacimento.

Qual ​​è esattamente il problema dell'anno 2038?

"Il problema dell'anno 2038 (noto anche come Unix Millennium Bug, Y2K38 per analogia con il problema Y2K) potrebbe causare il malfunzionamento di alcuni software del computer prima o nell'anno 2038. Il problema riguarda tutti i software e i sistemi che memorizzano l'ora di sistema come 32 firmato -bit intero e interpreta questo numero come il numero di secondi dalle 00:00:00 UTC del 1 gennaio 1970."

Perché si verifica e cosa succede quando si verifica?

Orari oltre le 03:14:07 UTC di martedì 19 gennaio 2038 verrà "avvolto" e memorizzato internamente come un numero negativo, che questi sistemi interpreteranno come un'ora nel 13 dicembre 1901 anziché nel 2038. Ciò è dovuto al fatto che il numero di secondi dall'epoca UNIX (1 gennaio 1970 00:00:00 GMT) avrà superato il valore massimo di un computer per un intero con segno a 32 bit.

Come lo risolviamo?

  • Utilizza tipi di dati lunghi (64 bit sono sufficienti)
  • Per MySQL (o MariaDB), se non hai bisogno delle informazioni sull'ora, considera l'utilizzo di DATE tipo di colonna. Se hai bisogno di una maggiore precisione, usa DATETIME anziché TIMESTAMP . Attenzione a quel DATETIME le colonne non memorizzano informazioni sul fuso orario, quindi la tua applicazione dovrà sapere quale fuso orario è stato utilizzato.
  • Altre possibili soluzioni descritte su Wikipedia
  • Aspetta che gli sviluppatori MySQL risolvano questo bug segnalato più di un decennio fa.

Ci sono possibili alternative al suo utilizzo, che non pongono un problema simile?

Prova, ove possibile, a utilizzare tipi grandi per memorizzare le date nei database:64 bit sono sufficienti - un tipo lungo lungo in GNU C e POSIX/SuS, oppure sprintf('%u'...) in PHP o nell'estensione BCmath.

Quali sono alcuni casi d'uso potenzialmente dannosi anche se non siamo ancora nel 2038?

Quindi un MySQL DATETIME ha un intervallo di 1000-9999, ma TIMESTAMP ha solo un intervallo di 1970-2038. Se il tuo sistema memorizza date di nascita, date future (ad es. mutui a 30 anni) o simili, ti imbatterai già in questo bug. Ancora una volta, non utilizzare TIMESTAMP se questo sarà un problema.

Cosa possiamo fare alle applicazioni esistenti che utilizzano TIMESTAMP, per evitare il cosiddetto problema, quando si verifica davvero?

Poche applicazioni PHP saranno ancora in circolazione nel 2038, anche se è difficile prevederlo poiché il Web non è ancora una piattaforma legacy.

Ecco un processo per modificare una colonna di una tabella del database per convertire TIMESTAMP a DATETIME . Inizia con la creazione di una colonna temporanea:

# 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`

Risorse