Mysql
 sql >> Base de données >  >> RDS >> Mysql

PHP &mySQL :Bug de l'année 2038 :Qu'est-ce que c'est ? Comment le résoudre?

J'ai marqué ceci comme un wiki communautaire, alors n'hésitez pas à le modifier à votre guise.

Quel est exactement le problème de l'an 2038 ?

"Le problème de l'année 2038 (également connu sous le nom de Unix Millennium Bug, Y2K38 par analogie avec le problème Y2K) peut entraîner l'échec de certains logiciels avant ou pendant l'année 2038. Le problème affecte tous les logiciels et systèmes qui stockent l'heure système sous la forme d'un 32 signé. -bit entier, et interprète ce nombre comme le nombre de secondes depuis 00:00:00 UTC le 1er janvier 1970."

Pourquoi cela se produit-il et que se passe-t-il lorsqu'il se produit ?

Heures au-delà de 03:14:07 UTC le mardi 19 janvier 2038 sera "bouclé" et stocké en interne sous la forme d'un nombre négatif, que ces systèmes interpréteront comme une heure du 13 décembre 1901 plutôt qu'en 2038. Cela est dû au fait que le nombre de secondes depuis l'époque UNIX (1er janvier 1970 00:00:00 GMT) aura dépassé la valeur maximale d'un ordinateur pour un entier signé 32 bits.

Comment le résoudre ?

  • Utilisez des types de données longs (64 bits suffisent)
  • Pour MySQL (ou MariaDB), si vous n'avez pas besoin des informations de temps, envisagez d'utiliser la DATE type de colonne. Si vous avez besoin d'une plus grande précision, utilisez DATETIME plutôt que TIMESTAMP . Attention, DATETIME les colonnes ne stockent pas d'informations sur le fuseau horaire, votre application devra donc savoir quel fuseau horaire a été utilisé.
  • Autres solutions possibles décrites sur Wikipedia
  • Attendez que les développeurs MySQL corrigent ce bogue signalé il y a plus de dix ans.

Existe-t-il des alternatives possibles à son utilisation, qui ne posent pas un problème similaire ?

Essayez dans la mesure du possible d'utiliser des types volumineux pour stocker les dates dans les bases de données :64 bits suffisent - un type long long dans GNU C et POSIX/SuS, ou sprintf('%u'...) en PHP ou l'extension BCmath.

Quels sont les cas d'utilisation potentiellement critiques même si nous ne sommes pas encore en 2038 ?

Donc un MySQL DATETIME a une plage de 1000 à 9999, mais TIMESTAMP n'a qu'une plage de 1970 à 2038. Si votre système stocke des dates de naissance, des dates futures (par exemple, des hypothèques sur 30 ans) ou similaires, vous allez déjà rencontrer ce bogue. Encore une fois, n'utilisez pas TIMESTAMP si cela pose problème.

Que pouvons-nous faire aux applications existantes qui utilisent TIMESTAMP, pour éviter le soi-disant problème, lorsqu'il se produit réellement ?

Peu d'applications PHP existeront encore en 2038, même si c'est difficile à prévoir car le Web n'est pas encore une plate-forme héritée.

Voici un processus pour modifier une colonne de table de base de données pour convertir TIMESTAMP à DATETIME . Cela commence par la création d'une colonne temporaire :

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

Ressources