PHP & mySQL: Ошибка 2038 года: Что это? Как решить его?

Я думал об использовании МЕТКИ ВРЕМЕНИ для хранения date+time, но я считал, что существует ограничение 2038 года на нем. Вместо того, чтобы задать мой вопрос оптом, я предпочел разбивать его в мелкие детали так, чтобы для неопытных пользователей было легко понять также. Так мой вопрос (вопросы):

  1. Какова точно проблема 2038 года?
  2. Почему происходит и что происходит, когда это происходит?
  3. Как мы решаем его?
  4. Там какие-либо возможные альтернативы к использованию его, которые не создают подобную проблему?
  5. Что мы можем сделать к существующим приложениям, которые используют МЕТКУ ВРЕМЕНИ, для предотвращения так называемой проблемы, когда она действительно происходит?

Заранее спасибо.

99
задан Corey Ballou 6 January 2010 в 11:45
поделиться

4 ответа

Я отметил это как вики-сообщество, так что не стесняйтесь редактировать на досуге.

Что именно является проблемой 2038 года?

"Проблема 2038 года (также известная как Unix Millennium Bug, Y2K38 по аналогии с проблемой Y2K) может привести к тому, что некоторые компьютерные программы выйдут из строя до или в 2038 году. Проблема затрагивает все программное обеспечение и системы, которые хранят системное время как подписанное 32-битное целое число, и интерпретируют это число как количество секунд с 00:00:00 UTC 1 января 1970 г."


Почему это происходит и что происходит, когда это происходит?

Время после 03:14:07 UTC во вторник 19 января 2038 г. будет "обернуто" и будет храниться внутренне как отрицательное число, которое эти системы будут интерпретировать как время 13 декабря 1901 г., а не 2038 г. Это связано с тем, что количество секунд с эпохи UNIX (1 января 1970 00:00:00 GMT) превысит максимальное значение компьютера для 32-битного подписанного целого.


Как это решить?

  • Используйте длинные типы данных (достаточно 64 бит)
  • Для MySQL (или MariaDB), если вам не нужна информация о времени, учитываемая при использовании типа столбца DATE. Если вам нужна более высокая точность, используйте DATETIME, а не TIMESTAMP. Обратите внимание, что колонки DATETIME не хранят информацию о часовом поясе, поэтому ваше приложение должно знать, какой часовой пояс был использован.
  • Другие возможные решения, описанные в Википедии
  • Подождите, пока MySQL devs исправит эту ошибку, о которой сообщалось более десяти лет назад.

Есть ли какие-нибудь возможные альтернативы его использованию, которые не создают подобной проблемы?

Попробуйте везде, где это возможно, использовать большие типы для хранения дат в базах данных: 64 бит достаточно - тип long long в GNU C и POSIX/SuS, или sprintf('%u'...) в PHP или расширении BCmath.


Каковы некоторые потенциальные случаи взлома, даже если мы еще не в 2038 году?

Итак, MySQL DATETIME имеет диапазон 1000-9999, а TIMESTAMP имеет диапазон только 1970-2038. Если в вашей системе хранятся даты рождения, будущие форвардные даты (например, ипотека на 30 лет) или подобные, то вы уже столкнетесь с этой ошибкой. Опять же, не используйте TIMESTAMP, если это будет проблемой.


Что мы можем сделать с существующими приложениями, использующими TIMESTAMP, чтобы избежать так называемой проблемы, когда она действительно возникнет?

В 2038 году будет еще мало PHP-приложений, хотя трудно предсказать, так как Веб еще не является старой платформой.

Вот процесс изменения столбца таблицы базы данных для преобразования TIMESTAMP в DATETIME. Он начинается с создания временного столбца:

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

Ресурсы

132
ответ дан 24 November 2019 в 05:05
поделиться

При использовании UNIX Timestamps для хранения дат, на самом деле вы используете 32-битные целые числа, которые хранят в памяти количество секунд, начиная с 1970-01-01; смотрите Unix Time

Что 32-битное число переполнится в 2038 году. Вот в чем проблема 2038 года.


Чтобы решить эту проблему, вы не должны использовать 32-битную UNIX метку времени для хранения дат -- это означает, что при использовании MySQL, вы не должны использовать TIMESTAMP, но DATETIME (см. 10.3.1. Типы DATETIME, DATE и TIMESTAMP) :

Тип DATETIME используется, когда вы нужны значения, содержащие как дату, так и информация о времени. Поддерживаемый диапазон это '1000-01-01 00:00:00' to '9999-12-31 23:59:59'.

Тип данных TIMESTAMP имеет диапазон от '1970-01-01 00:00:01' UTC до '2038-01-19 03:14:07' UTC.


Лучшее, что вы можете сделать со своим приложением (вероятно), чтобы избежать/устранить эту проблему, это не использовать TIMESTAMP, а DATETIME для столбцов, которые должны содержать даты, которые не находятся между 1970 и 2038 годами.

Одна маленькая заметка : существует очень высокая вероятно (по статистике), что ваше приложение было переписано довольно много раз до 2038 ^^^ Так что, возможно, если вам не придется иметь дело с датами в будущем, вам не придется заботиться об этой проблеме с текущей версией вашего приложения....

12
ответ дан 24 November 2019 в 05:05
поделиться

Быстрый поиск в Гугле поможет: Проблема 2038 года

  1. Проблема 2038 года (также известная как Unix Millennium Bug, Y2K38 по аналогии с проблемой Y2K) может привести к отказу некоторых компьютерных программ до или в 2038 году
  2. Проблема затрагивает все программное обеспечение и системы, которые хранят системное время как подписанное 32-битное целое число, и интерпретирует это число как количество секунд с 00:00:00 по UTC 1 января 1970 года. Последнее время, которое может быть представлено таким образом - 03:14:07 UTC во вторник 19 января 2038 года. Время после этого момента "обернется" и будет храниться внутренне как отрицательное число, которое эти системы будут интерпретировать как дату в 1901, а не в 2038
  3. Для существующих комбинаций CPU/OS, существующих файловых систем или существующих двоичных форматов данных
7
ответ дан 24 November 2019 в 05:05
поделиться

http://en.wikipedia.org/wiki/Year_2038_problem имеет большинство деталей

В общем:

1) + 2) Проблема в том, что многие системы хранят информацию о дате в виде 32-битной подписи int, равной количеству секунд с 1/1/1970. Последняя дата, которая может храниться в таком виде - 03:14:07 UTC во вторник 19 января 2038 года. Когда это произойдет, int "обернется" и будет сохранена как отрицательное число, которое будет интерпретировано как дата 1901 года. Что именно произойдет тогда, зависит от системы, но достаточно сказать, что это, вероятно, не будет хорошо для любого из них!

Для систем, которые хранят даты только в прошлом, тогда, думаю, вам не нужно беспокоиться какое-то время! Основная проблема заключается в системах, которые работают с датами в будущем. Если ваша система должна работать с датами 28 лет в будущем, то вы должны начать беспокоиться сейчас!

3) Используйте один из доступных альтернативных форматов дат или перейдите на 64-битную систему и используйте 64-битные дюймы. Или для баз данных используйте альтернативный формат метки времени (например, для MySQL используйте DATETIME)

4) См. 3!

5) Смотрите 4!!! ;)

.
2
ответ дан 24 November 2019 в 05:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: