138 votes

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

Je pensais utiliser TIMESTAMP pour stocker la date et l'heure, mais j'ai lu qu'il y avait une limitation à l'année 2038. Au lieu de poser ma question en bloc, j'ai préféré la décomposer en petites parties afin qu'elle soit facile à comprendre pour les utilisateurs novices également. Donc ma (mes) question(s) :

  1. Quel est exactement le problème de l'année 2038 ?
  2. Pourquoi cela se produit-il et que se passe-t-il quand cela se produit ?
  3. Comment le résoudre ?
  4. Existe-t-il des alternatives possibles à son utilisation, qui ne posent pas un problème similaire ?
  5. Que pouvons-nous faire aux applications existantes qui utilisent TIMESTAMP, pour éviter le soi-disant problème, lorsqu'il se produit réellement ?

Merci d'avance.

181voto

cballou Points 13804

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

Quel est exactement le problème de l'année 2038 ?

"Le problème de l'année 2038 (également connu sous le nom de bogue du millénaire d'Unix, Y2K38 par analogie avec le problème de l'an 2000) peut entraîner la défaillance de certains logiciels informatiques avant ou pendant l'année 2038. Le problème affecte tous les logiciels et systèmes qui stockent l'heure du système sous la forme d'un nombre entier 32 bits signé, et interprètent 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 quand cela se produit ?

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


Comment le résoudre ?


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

Essayez autant que possible d'utiliser de grands types pour stocker les dates dans les bases de données : 64 bits sont suffisants - un type long long dans GNU C et POSIX/SuS, ou encore sprintf('%u'...) en PHP ou dans l'extension BCmath.


Quels sont les cas d'utilisation potentiellement innovants, 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 à terme (par exemple, des hypothèques sur 30 ans) ou autres, vous rencontrerez déjà ce problème. Encore une fois, n'utilisez pas TIMESTAMP si cela risque de poser 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, bien qu'il soit difficile de le prévoir car le web n'est pas encore une plate-forme héritée.

Voici une procédure pour modifier une colonne de table de base de données pour la 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

16voto

Pascal MARTIN Points 195780

Lorsque vous utilisez des horodateurs UNIX pour stocker des dates, vous utilisez en fait un nombre entier de 32 bits, qui compte le nombre de secondes depuis le 01-01-1970 ; cf. Temps Unix

Ce nombre de 32 bits débordera en 2038. C'est le problème de 2038.

Pour résoudre ce problème, vous ne devez pas utiliser un timestamp UNIX 32 bits pour stocker vos dates -- ce qui signifie que, lorsque vous utilisez MySQL, vous ne devez pas utiliser TIMESTAMP mais DATETIME (voir 10.3.1. Les types de DATE, DATE et HORAIRE ) :

Le site DATETIME est utilisé lorsque vous ont besoin de valeurs qui contiennent à la fois la date et des informations sur l'heure. La plage prise en charge est '1000-01-01 00:00:00' à '9999-12-31 23:59:59' .

Le site TIMESTAMP Le type de données a une plage de '1970-01-01 00:00:01' UTC à '2038-01-19 03:14:07' UTC.

Le site (probablement) la meilleure chose que vous puissiez faire à votre application pour éviter/réparer ce problème est de ne pas utiliser TIMESTAMP mais DATETIME pour les colonnes qui doivent contenir des dates qui ne sont pas comprises entre 1970 et 2038.

Une petite remarque, cependant : il y a une très forte probabilité (statistiquement parlant) que votre application aura été réécrite plusieurs fois avant 2038 ^^ Donc peut-être, si vous n'avez pas à vous occuper des dates dans le futur, vous n'aurez pas à vous occuper de ce problème avec la version actuelle de votre application...

8voto

Rubens Farias Points 33357

Une recherche rapide sur Google fera l'affaire : Problème de l'année 2038

  1. Le problème de l'année 2038 (également connu sous le nom de bogue du millénaire d'Unix, Y2K38 par analogie avec le problème de l'an 2000) peut entraîner la défaillance de certains logiciels informatiques avant ou pendant l'année 2038.
  2. Le problème affecte tous les logiciels et systèmes qui stockent l'heure du système sous la forme d'un nombre entier signé de 32 bits, et interprètent ce nombre comme le nombre de secondes depuis 00:00:00 UTC le 1er janvier 1970. La dernière heure pouvant être représentée de cette manière est 03:14:07 UTC le mardi 19 janvier 2038. Les heures au-delà de ce moment seront "enveloppées" et stockées en interne comme un nombre négatif, que ces systèmes interpréteront comme une date en 1901 plutôt qu'en 2038.
  3. Il n'y a pas de solution facile à ce problème pour les combinaisons CPU/OS existantes, les systèmes de fichiers existants ou les formats de données binaires existants.

2voto

Addsy Points 2061

http://en.wikipedia.org/wiki/Year_2038_problem a la plupart des détails

En résumé :

1) + 2) Le problème est que de nombreux systèmes stockent les informations relatives à la date sous la forme d'un nombre entier signé de 32 bits égal au nombre de secondes écoulées depuis le 1/1/1970. La dernière date qui peut être stockée de cette manière est 03:14:07 UTC le mardi 19 janvier 2038. Lorsque cela se produira, l'int sera "enveloppé" et stocké comme un nombre négatif qui sera interprété comme une date en 1901. Ce qui se passera alors varie d'un système à l'autre, mais il suffit de dire que ce ne sera probablement pas bon pour aucun d'entre eux !

Pour les systèmes qui ne mémorisent que des dates dans le passé, je suppose que vous n'avez pas à vous inquiéter avant un certain temps ! Le principal problème concerne les systèmes qui travaillent avec des dates dans le futur. Si votre système doit travailler avec des dates situées 28 ans dans le futur, vous devriez commencer à vous inquiéter dès maintenant !

3) Utilisez l'un des formats de date alternatifs disponibles ou passez à un système 64 bits et utilisez des ints 64 bits. Ou pour les bases de données, utilisez un autre format d'horodatage (par exemple, pour MySQL, utilisez DATETIME).

4) Voir 3 !

5) Voir 4 ! !! ;)

1voto

Dexter Points 1422

Bros, si vous avez besoin d'utiliser PHP pour afficher des horodatages, c'est la MEILLEURE solution PHP sans changer le format UNIX_TIMESTAMP.

Utilisez une fonction custom_date(). À l'intérieur de celle-ci, utilisez la fonction DateTime. Voici la solution DateTime .

Tant que vous avez UNSIGNED BIGINT(8) comme timestamps dans la base de données. Tant que vous avez PHP 5.2.0 ++.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X