Question

Je pensais à l'aide TIMESTAMP pour stocker la date +, mais je lis qu'il ya une limitation de l'année 2038 sur elle. Au lieu de poser ma question en vrac, je préférais le casser en petits morceaux afin qu'il soit facile pour les utilisateurs novices à comprendre aussi bien. Donc, ma question (s):

  1. Quel est exactement le problème de l'an 2038?
  2. Pourquoi faut-il se produit et ce qui se passe quand il se produit?
  3. Comment peut-on résoudre?
  4. Y a-t-il des solutions de rechange à l'utiliser, qui ne posent pas de problème similaire?
  5. Que pouvons-nous faire pour les applications existantes qui utilisent TIMESTAMP, pour éviter le problème que l'on appelle, quand il se produit vraiment?

Merci d'avance.

Était-ce utile?

La solution

J'ai marqué cela comme un wiki communautaire alors ne hésitez pas à modifier à votre guise.

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

"Le problème de l'an 2038 (également connu sous le nom Bug Unix Millennium, Y2K38 par analogie au problème Y2K) peut causer des logiciels échouer avant ou durant l'année 2038. Le problème affecte tous les logiciels et les systèmes qui stockent le temps de système un entier signé 32 bits, et interpréter ce nombre comme le nombre de secondes depuis 00:00:00 UTC le 1er Janvier 1970. "


Pourquoi faut-il se produit et ce qui se passe quand il se produit?

Les temps au-delà de 03:14:07 UTC le mardi 19 Janvier 2038 « enrouler autour » et être stockées en interne comme un nombre négatif, ces systèmes interpréteront comme un temps en Décembre 13, 1901 plutôt que dans 2038. Ceci est dû au fait que le nombre de secondes écoulées depuis l'époque UNIX (1 Janvier 1970 à 00:00:00 GMT) aura dépassé la valeur maximale d'un ordinateur pour un entier signé 32 bits.


Comment peut-on résoudre?

  • Utiliser des types de données à long (64 bits est suffisante)
  • Pour MySQL (ou MariaDB), si vous n'avez pas besoin des informations de temps pensez à utiliser le type de colonne de DATE. Si vous avez besoin d'une plus grande précision, utilisez DATETIME plutôt que TIMESTAMP. Méfiez-vous que les colonnes DATETIME ne stockent pas d'informations sur le fuseau horaire, de sorte que votre demande sera de savoir quel fuseau horaire a été utilisé.
  • Autres solutions possibles décrites sur Wikipedia
  • Attendez que MySQL devs pour corriger ce bug a rapporté il y a plus d'une décennie.

Y a-t-il des alternatives possibles à l'utiliser, qui ne posent pas de problème similaire?

Essayer autant que possible d'utiliser de grands types pour le stockage de dates dans les bases de données:. 64 bits est suffisante - un type long long dans GNU C et POSIX / SuS ou sprintf('%u'...) en PHP ou l'extension BCMath


Qu'est-ce que certains cas d'utilisation potentiellement casser même si nous ne sommes pas encore en 2038?

DATETIME a une portée de 1000- 9999, mais TIMESTAMP a seulement une gamme de 1970-2038. Si votre système stocke, date de naissance des dates futures à terme (par exemple 30 hypothèques année), ou similaire, vous allez déjà à courir dans ce bogue. Encore une fois, ne pas utiliser TIMESTAMP si cela va être un problème.


Que pouvons-nous faire pour les applications existantes qui utilisent TIMESTAMP, pour éviter le problème que l'on appelle, quand il se produit vraiment?

Peu d'applications PHP seront encore là en 2038, mais il est difficile de prévoir que le web encore à peine une plate-forme existante.

Voici un processus pour modifier une colonne de table de base de données pour convertir TIMESTAMP à DATETIME. Il 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

Autres conseils

Lorsque vous utilisez UNIX Horodatage pour stocker les dates, vous utilisez en fait un entiers 32 bits, qui comptabilise le nombre de secondes écoulées depuis le 1970-01-01; voir Unix Temps

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


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

  

Le type de DATETIME est utilisé lorsque vous   ont besoin de valeurs qui contiennent à la fois la date et   information en temps. La plage prise en charge   est à '1000-01-01 00:00:00'   '9999-12-31 23:59:59'.

     

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


(probablement) meilleure chose que vous pouvez faire pour votre application afin d'éviter / régler ce problème est de ne pas utiliser TIMESTAMP, mais DATETIME pour les colonnes qui doivent contenir des dates qui ne sont pas entre 1970 et 2038.

Une petite note, cependant: il y a un doute très élevé (statistiquement parlant) que votre demande aura été réécrite tout à fait deux ou trois fois avant 2038 ^^ Alors peut-être, si vous ne « t doivent faire face à des dates dans l'avenir, vous ne devez prendre soin de ce problème avec la version actuelle de votre application ...

Une recherche rapide sur Google fera l'affaire: Année 2038 problème

  1. L'année 2038 problème (également connu sous le nom Bug Unix Millennium, Y2K38 par analogie au problème Y2K) peut causer des logiciels échouer avant ou dans l'année 2038
  2. Le problème affecte tous les logiciels et les systèmes qui stockent le temps du système comme un entier signé 32 bits et interpréter ce nombre comme le nombre de secondes depuis 00:00:00 UTC le 1er Janvier 1970. La dernière fois que peut être représenté de cette façon est 03:14:07 UTC le mardi 19 janvier 2038. les temps au-delà de ce moment sera « enrouler autour » et être stockées en interne comme un nombre négatif, ces systèmes interpréteront comme une date en 1901 plutôt que 2038
  3. Il n'y a pas de solution facile à ce problème pour les combinaisons existantes CPU / OS, les systèmes de fichiers existants, ou des formats de données binaires existant

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

En résumé:

1) + 2) Le problème est que les informations de date de stocker de nombreux systèmes comme 32 bits signé int égal au nombre de secondes depuis le 1/1/1970. La dernière date à laquelle peuvent être enregistrées comme UTC est 03:14:07 le mardi 19 Janvier 2038. Lorsque cela se produit l'int va « enrouler autour » et être stocké sous forme d'un nombre négatif qui sera interprété comme une date en 1901. Que se passera-exactement alors, varie d'un système à mais il suffit de dire que ce ne sera probablement pas bon pour aucun d'entre eux!

Pour les systèmes qui ne stockent les dates dans le passé, alors je suppose que vous ne devez pas vous inquiéter pendant un certain temps! Le principal problème est avec les systèmes qui fonctionnent avec des dates dans l'avenir. Si votre système a besoin de travailler avec des dates de 28 ans dans l'avenir, alors vous devriez commencer à se soucier maintenant!

3) Utilisez l'un des formats de date alternatives disponibles ou passer à un système 64 bits et utiliser ints 64 bits. Ou pour les bases de données utilisent un format d'horodatage de remplacement (par exemple pour MySQL utiliser DATETIME)

4) Voir 3!

5) Voir 4 !!! ;)

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

A l'aide d'une fonction custom_date (). A l'intérieur, utilisez le DateTime. Voici la solution DateTime .

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

Comme je l'ai did't veulent passer quoi que ce soit, je demandai à mon back-end (MSSQL) pour faire ce travail au lieu de PHP!

$qry = "select DATEADD(month, 1, :date) next_date ";
$rs_tmp = $pdo->prepare($qry);
$rs_tmp->bindValue(":date", '2038/01/15');
$rs_tmp->execute();
$row_tmp = $rs_tmp->fetch(PDO::FETCH_ASSOC);

echo $row_tmp['next_date'];

ne peut être une manière efficace, mais il fonctionne.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top