Как реализовать год 2038 Проблема Исправлена ошибка в PHP-приложениях, использующих временные метки Unix - Невероятный блог временной шкалы времени онлайн урок.


Введение

Чтобы объяснить проблему, в этой статье описаны несколько концепций, связанных с отметками времени UNIX. Части статьи цитируют Википедию.

Что такое временная метка?

При вычислении временная метка относится к использованию числа для представления значения времени, поэтому вы можете установить временный порядок среди множества событий.

Atimestamp- время, в которое событие записывается компьютером, а не время самого события. Во многих случаях разница может быть несущественной: время, в которое событие записывается временной меткой (например, введенной в файл журнала), должно быть близко к времени события.

Эти данные обычно представлены в согласованном формате, что позволяет легко сравнивать две разные записи и отслеживать прогресс с течением времени. Практика записи временных меток согласованным образом вместе с фактическими данными называется временной привязкой. Последовательная нумерация событий также иногда называется timestamping.

Временные метки обычно используются для регистрации событий или последовательности событий (SOE), и в этом случае каждое событие в журнале или SOE помечено меткой времени.

В файловых системах отметка времени может означать сохраненную дату и время создания или изменения файла.

Методы временной привязки используются во множестве вычислительных полей: от управления сетью и компьютерной безопасности до контроля параллелизма. Например, сеть heartbeat использует timestamping для мониторинга узлов в кластере высокой доступности.

Что такое отметка времени UNIX?

Время UNIX (также известное как время POSIX или время эпохи) - это система для описания моментов времени, определяемая как количество секунд, прошедших с 00:00:00. Скоординированное универсальное время (UTC), четверг, 1 января 1970 г. минус количество секунд прыжка, которые произошли с тех пор.

Он широко используется в UNIX-подобных и многих других операционных системах и форматах файлов. Поскольку одна и та же временная метка может относиться к двум разным моментам времени вокруг секунды скачка, это не является ни линейной мерой времени, ни истинным представлением UTC.

Время UNIX может быть проверено в большинстве систем UNIX, введяdate +% sв командной строке.

Каковы пределы отметки времени Unix?

32-разрядное представление времени UNIX закончится после завершения 2 147 473 647 секунд с начала (00:00:00 1 января 1970 года), 19 января 2038 года 03:14:08 GMT. Это называется проблемой «Год 2038», когда 32-разрядное время UNIX будет переполняться и будет считать фактический счетчик отрицательным.

Ошибка года 2038

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

Такие реализации не могут кодировать время после 03:14:07 UTC 19 января 2038 года, проблема, аналогичная, но не совсем аналогичная проблеме Y2K (также известная как «Ошибка тысячелетия»), в которой двузначные значения, представляющие число годы с 1900 года не могут кодироваться в 2000 году или позже.

Большинство 32-разрядных Unix-подобных систем хранят и обрабатывают время в этом формате времени Unix, поэтому проблему 2038 года иногда называют ассоциацией Unix Millennium Bug.

Многие используемые сегодня структуры данных имеют 32-битные представления времени, встроенные в их структуру. Полный список этих структур данных практически невозможно получить, но существуют хорошо известные структуры данных, которые имеют временную проблему Unix:

- Файловые системы (многие файловые системы используют только 32 бита для представления времени в inodes)
- Двоичный файл форматы (которые используют 32-битные поля времени)
- Базы данных (которые имеют 32-битные поля времени)
- Языки запросов базы данных, такие как SQL, которые имеют UNIX_TIMESTAMP (), как команды

Примеры систем, использующих структуры данных, которые могут содержать 32- битные представления времени включают:

- системы COBOL 1970-х годов до 1990-х годов, которые не были заменены 2038-совместимыми системами
- Встроенные фабрики, подсистемы управления и мониторинга нефтеперерабатывающих заводов
- Ассортимент медицинских устройств
- Ассортимент военных устройств

Любая система, использующая структуры данных, содержащие 32-битные представления времени, представит риск. Степень риска зависит от способа отказа.

PHP и отметка времени UNIX

Как и многие языки, PHP широко использует время UNIX и особенно в своих стандартных функциях календаря. Многие алгоритмы, например, настройки срока действия cookie, основаны на этой отметке времени UNIX. Функции PHP, такие как time (), mktime (), date () и многие другие функции, использовали время Unix для работы.

Почему альтернатива может быть полезной?

Время UNIX, как мы видели, начинается с 1 января 1970 года 00:00:00, поэтому, если вы родились до этой даты, вы не можете в этот момент точно узнать или даже приблизиться к количеству секунд, которые вы потратили на Земля. Может быть сложно вычислить время, прошедшее с вашего текущего возраста, используя отметку времени UNIX.

Многие веб-приложения, основанные на языке PHP, предлагают пользователям вычислить их возраст, и они действительно не могли этого сделать, если они не использовали альтернативу функциям календаря PHP, которые не используют временную метку UNIX. Конечно, если вы думаете, что будете покупать свой первый yatch только в 2039 году, вы также не можете знать, сколько секунд осталось до этой покупки.

По этим и другим причинам было полезно найти альтернативу временной отметке UNIX и многим функциям календаря PHP, которые полагаются на нее.

Как работать вокруг ошибки 2038 года в Pure PHP?

На данный момент нет конкретных решений для этой проблемы. Конечно, есть много решений, но все они индустриальные, например: замените все 32-битные системы на 64 бита до 2038 года. И это самое простое решение, которое нашли компьютерные ученые.

Но не паникуйте, эта статья здесь, чтобы помочь вам найти решение в несколько шагов по этому вопросу и позволить вам узнать, сколько секунд осталось до покупки вашего красивого yatch или самолета.

Первый шаг: выберите ваши соглашения

Время UNIX начинается в1970 году, поэтому мы решили помочь старшим ребятам, запустив наше решение timestamp в год 0. Таким образом, наша начальная точка будет первым январем года 0 в 00:00:00,

Второй шаг: алгоритм

- Сначала мы выбираем пример даты и времени 1970-09-09 00:00:00

- Затем вычислите число високосного года с года 0 до выбранной вами даты здесь в 1970 году: это дает нас 477 високосных годов. Назовем это число $ i. Обратите внимание, что мы используем григорианский алгоритм для високосного года, если ($ x modulo 4 == 0 & amp; $ x modulo 100! = 0 или $ x modulo 400 == 0) это високосный год, иначе это общий год,

- Теперь выведите $ i из выбранного года здесь 1970: это даст вам общее число, которое мы будем называть $ j.

- Теперь мы хотим узнать количество дней, прошедших с первого января выбранного года в 1970 году: вы должны следить за тем, что год может быть високосным годом.

Високосный год (также известный как промежуточный год или год биссектиля) - это календарный год, содержащий один дополнительный день (или, в случае лунносолнечных календарей, месяц), добавленный для сохранения календарного года, синхронизированного с астрономическим или сезонным годом,

Поскольку сезоны и астрономические события не повторяются в течение целого числа дней, календари, которые имеют одинаковое количество дней в каждом году, со временем меняются по отношению к событию, которое должен отслеживать год.

Вставляя (также называемый интеркалируя) дополнительный день или месяц в год, можно изменить дрейф. Год, который не является високосным годом, называется общим годом. Например, в григорианском календаре каждый високосный год имеет 366 дней вместо обычных 365, продлевая февраль до 29 дней, а не обычный 28.

Посмотрите на свою выбранную дату месяца и за считанные дни с первого января года до этого месяца - 1.

В нашем примере мы должны взять все дни с первого января 1970 года по 31 августа (здесь $ month - 1 == (9 - 1) == 8 == август).

1970 не является високосным годом, поэтому мы имеем:

$ days = array (0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365);

, и если мы назовем $ k этим числом, то имеем $ k = 243 дня.

Теперь мы должны принять количество дней, прошедших с начала месяца (здесь 9): и прошло 9 дней. Мы будем называть это число $ l.

- вычислить количество дней, прошедших с первого января года 0 до выбранной вами даты, и это будет очень просто со всеми, что мы делаем с самого начала:

$ days = ($ i * 366 + $ j * 365 + $ k + $ l;)

- Наконец Вычислите количество секунд, прошедших с первого дня года 0 в 00:00:00 до выбранной даты:

$ day = 86400;
$ hour = 3600;
$ min = 60;
$ sec = 1;

$ timestamp = ($ days * 86400 + $ h (выбранная дата) * $ hour + $ m (выбранная дата) * $ min + $ sec) - 86400.

Мы вычитаем 86400 секунд, потому что последний день не заполнен и только что представлен временем.
, и все сделано.

Для выбранной нами даты 1970 - 09 - 09 00:00:00 мы имеем:

62188819200 секунд.

Если вы обнаружили, что результат тот же, тогда вы добры.

Загрузить классы PHP для реализации длинных временных меток

Здесь вы можете найти решение для вычисления секунд, прошедших с года 0 здесь . Вы можете даже отменить это. Ожидая следующего учебника о том, как найти точную дату, когда вы только что получили метку времени Incredible, вы уже видите реализацию здесь .

И для предоставления полной альтернативы для отметки времени UNIX в чистом PHP вы можете видеть очень точную разницу между датами и временем между двумя датами на основе алгоритма выше здесь , а также очень точное различие дат между двумя датами на основе тот же алгоритм, и по той же мысли этот Невероятный день недели искатель в чистом PHP для любой даты .