Проблема 2038 года

Материал из Википедии — свободной энциклопедии
Перейти к навигации Перейти к поиску
Пример, демонстрирующий сброс даты и времени (в 03:14:08 UTC 19 января 2038 года) при их представлении в 32-битном формате

Проблема 2038 года в вычислительной технике — ожидаемые сбои в программном обеспечении 19 января 2038 года. Данная проблема затронет программы и системы, использующие 32-битный формат представления даты и времени по стандарту POSIX (Unix-время), согласно которому они выражаются числом секунд, прошедших с полуночи 1 января 1970 года по Всемирному координированному времени (UTC) (так называемой эпохи Unix). Такое представление даты и времени используется, в частности, в Unix-подобных операционных системах и в Microsoft Windows (из-за повсеместного использования языков программирования C и C++).

Тип данных time_t, используемый для представления времени (целого числа секунд) в языках программирования C и C++, в большинстве старых (разработанных до середины 1990-х годов) 32-битных операционных систем является 32-битным целым со знаком. Самые поздние дата и время, которые могут быть представлены таким типом данных в стандарте POSIX — 03:14:07 UTC 19 января 2038 года.

Более поздние дата и время будут некорректно представлены в таком формате как отрицательное значение, тем самым как бы «закольцевав» ось времени (поскольку отрицательное число может быть воспринято программами как время в 1901, 1969 или 1970 году в зависимости от реализации). В результате этого любые расчёты, включающие дату и время позже 03:14:07 UTC 19 января 2038 года, могут привести к сбою программы либо к ошибочным вычислениям.

Для проблемы 2038 года не существует единого простого решения, подходящего для всех имеющихся комбинаций операционных систем и прикладного программного обеспечения. Изменение определения типа time_t на 64-битное целое нарушает бинарную совместимость программ, существующих хранимых данных и вообще всего, что использует данный тип в 32-битном формате. В свою очередь, приведение time_t к целому без знака может нарушать работу программ, вычисляющих разницу во времени, при работе с датой и временем раньше эпохи Unix (до 1970 года).

В большинстве операционных систем для 64-битных компьютерных архитектур тип time_t определён как 64-битное целое со знаком. В настоящее время (2025 год) происходит переход на такие архитектуры, и ожидается, что к 2038 году он будет завершён.

Тем не менее, 32-битный формат time_t включён в ряд спецификаций форматов файлов, таких как повсеместно распространённый архивный формат ZIP. Поскольку формат файла может существовать в течение времени, за которое сменятся многие поколения компьютеров, это означает, что проблема 2038 года останется актуальной и в обозримом будущем.

Введение 64-битного формата существенно отдаляет момент «закольцовывания», поскольку максимально представимое значение даты и времени при этом составляет секунд (один бит отведён под знак числа) от эпохи Unix — иными словами, оно произойдёт примерно через 292 миллиарда лет[a], что намного больше возраста Вселенной.

Проблема 2038 года актуальна и для 32-битных версий Windows, так как значительная часть самой системы и большое число программ для неё написано на C и C++. Разработчики Windows утверждают[1], что исправили большинство мест в коде, подверженных этой проблеме, однако они не могут дать никаких гарантий по поводу стороннего ПО.

Начиная с версии 5.6 ядра Linux проблема решена, но по состоянию на 2020 год существует огромное количество ПО, которое всё ещё нужно исправить[2].

Значения даты и времени, представимые типом данных TIMESTAMP в популярных СУБД MySQL и Microsoft SQL Server, ограничены диапазоном от 1970-01-01 00:00:01 UTC до 2038-01-19 03:14:07 UTC; такое же ограничение возникает при представлении Unix-времени типом INT. Для устранения данного ограничения необходимо использовать тип BIGINT. Тип DATE в MySQL поддерживает значения даты в диапазоне от 1000-01-01 до 9999-12-31, тип DATETIME — значения даты и времени в диапазоне от 1000-01-01 00:00:00 до 9999-12-31 23:59:59[3].

Примечания

[править | править код]

Комментарии

[править | править код]
  1. секунд — это примерно 292 277 024 627 лет.
  1. Year 2038 problem — GES on Windows 7 (англ.). MSDN Blogs (15 марта 2010). Дата обращения: 5 января 2011. Архивировано из оригинала 9 июля 2011 года.
  2. Michael Larabel. Linux 5.6 Is The First Kernel For 32-Bit Systems Ready To Run Past Year 2038 (англ.) (29 января 2020). Дата обращения: 13 февраля 2020. Архивировано 6 февраля 2020 года.
  3. MySQL 8.4 Reference Manual: The DATE, DATETIME, and TIMESTAMP Types (англ.). Дата обращения: 26 ноября 2024. Архивировано 2 мая 2024 года.