Проблема 2038 года
( Проблема 2038 года также известная как Y2038 , [ 1 ] Y2K38 , супербаг Y2K38 или Эпохалипс [ 2 ] [ 3 ] ) — это проблема вычисления времени , из-за которой некоторые компьютерные системы не могут отображать время после 03:14:07 UTC 19 января 2038 года.
Проблема существует в системах, которые измеряют время Unix — количество секунд, прошедших с Unix эпохи (00:00:00 UTC 1 января 1970 года) — и сохраняют его в виде 32-битного целого числа со знаком . Тип данных способен представлять только целые числа от −(2 31 ) и 2 31 − 1 , что означает, что последнее время, которое может быть правильно закодировано, равно 2. 31 − 1 секунда после эпохи (03:14:07 UTC 19 января 2038 г.). Попытка увеличения до следующей секунды (03:14:08) приведет к переполнению целого числа , установив его значение в −(2 31 ) какие системы будут интерпретировать как 2 31 секунды до начала эпохи (20:45:52 UTC 13 декабря 1901 г.). По своей природе проблема аналогична проблеме 2000 года , с той разницей, что проблема 2000 года имела дело с числами по основанию 10 , тогда как проблема 2038 года включала числа по основанию 2 .
Аналогичные ограничения памяти будут достигнуты в 2106 году , когда системы, хранящие время Unix как беззнаковое (а не знаковое) 32-битное целое число, переполнятся 7 февраля 2106 года в 06:28:15 UTC.
Компьютерные системы, использующие время для критических вычислений, могут столкнуться с фатальными ошибками, если не решить проблему 2038 года. Некоторые приложения, использующие будущие даты, уже столкнулись с этой ошибкой. [ 4 ] [ 5 ] Наиболее уязвимыми системами являются те, которые обновляются редко или никогда не обновляются, например устаревшие и встроенные системы . Современные системы и обновления программного обеспечения устаревших систем решают эту проблему, используя 64-битные целые числа со знаком вместо 32-битных целых чисел, для переполнения которых потребуется 292 миллиарда лет, что примерно в 21 раз превышает предполагаемый возраст Вселенной .
Причина
[ редактировать ]Многие компьютерные системы измеряют время и дату, используя время Unix , международный стандарт цифрового хронометража. Время Unix определяется как количество секунд, прошедших с 00:00:00 UTC 1 января 1970 года (произвольно выбранное время, основанное на создании первой системы Unix ), которое было названо эпохой Unix . [ 6 ]
Время в Unix исторически кодировалось как 32-битное целое число со знаком , тип данных, состоящий из 32 двоичных цифр (битов), которые представляют целочисленное значение, причем «знак» означает, что число может представлять как положительные, так и отрицательные числа, а также ноль; и обычно хранится в формате дополнения до двух . [ а ] Таким образом, 32-битное целое число со знаком может представлять только целочисленные значения из −(2 31 ) до 2 31 − 1 включительно. Следовательно, если для хранения времени Unix используется 32-битное целое число со знаком, самое позднее время, которое можно сохранить, равно 2. 31 − 1 (2 147 483 647) секунд после эпохи, то есть 03:14:07 во вторник, 19 января 2038 г. [ 7 ] Системы, которые пытаются увеличить это значение еще на одну секунду до 2. 31 секунд после эпохи (03:14:08) произойдет переполнение целого числа , что приведет к непреднамеренному изменению знакового бита для обозначения отрицательного числа. Это изменит целочисленное значение на —(2 31 ), или 2 31 секунд до эпохи, а не после , что системы будут интерпретировать как 20:45:52 в пятницу, 13 декабря 1901 года. С этого момента системы продолжат отсчет вверх, к нулю, а затем снова вверх до положительных целых чисел. Поскольку многие компьютерные системы используют вычисления времени для выполнения критических функций, эта ошибка может создать серьезные проблемы.
Уязвимые системы
[ редактировать ]Любая система, использующая структуры данных со знаковыми 32-битными представлениями времени, подвержена риску сбоя. Полный список этих структур данных получить практически невозможно, но существуют хорошо известные структуры данных, которые имеют проблему времени Unix:
- Файловые системы, использующие 32 бита для представления времени в индексных дескрипторах.
- Двоичные форматы файлов с 32-битными полями времени.
- Базы данных с 32-битными полями времени
- Языки запросов к базе данных (например, SQL ), которые имеют
UNIX_TIMESTAMP()
-подобные команды
Встраиваемые системы
[ редактировать ]встраиваемые системы , использующие даты для вычислений или диагностики. Проблема Y2038, скорее всего, повлияет на [ 1 ] Несмотря на современное обновление технологий компьютерных систем, которое занимает 18–24 месяца , встроенные системы рассчитаны на срок службы машины, компонентом которой они являются. Вполне возможно, что некоторые из этих систем все еще будут использоваться в 2038 году. Обновление программного обеспечения, на котором работают эти системы, может быть непрактичным, а в некоторых случаях невозможным, что в конечном итоге потребует замены, если необходимо исправить 32-битные ограничения.
Многие транспортные системы, от самолетов до автомобилей, широко используют встроенные системы. В автомобильных системах это может включать антиблокировочную систему тормозов (ABS), электронную систему контроля устойчивости (ESC/ESP), антипробуксовочную систему (TCS) и автоматический полный привод ; самолеты могут использовать инерциальные системы наведения и приемники GPS . [ б ] Еще одним важным применением встроенных систем являются устройства связи, включая сотовые телефоны и устройства с поддержкой Интернета (например, маршрутизаторы , точки беспроводного доступа , IP-камеры ), которые полагаются на сохранение точного времени и даты и все чаще основаны на Unix-подобных операционных системах. Например, из-за проблемы Y2038 некоторые устройства под управлением 32-битной версии Android аварийно завершают работу и не перезагружаются при изменении времени на эту дату. [ 8 ]
Однако это не означает, что все встроенные системы пострадают от проблемы Y2038, поскольку многие такие системы не требуют доступа к датам. Для тех, кто это сделает, те системы, которые отслеживают только разницу между временем/датами, а не абсолютными временем/датами, по природе вычислений не будут испытывать серьезных проблем. Это относится к автомобильной диагностике, основанной на установленных законом стандартах, таких как CARB ( Калифорнийский совет по воздушным ресурсам ). [ 9 ]
Ранние проблемы
[ редактировать ]В мае 2006 года появились сообщения о раннем проявлении проблемы Y2038 в программном обеспечении AOLserver . Программное обеспечение было разработано с учетом особенностей обработки запросов к базе данных, время ожидания которых «никогда» не должно истекать. Вместо того, чтобы специально обрабатывать этот особый случай, первоначальный проект просто указывал произвольную дату тайм-аута в будущем с конфигурацией по умолчанию, указывающей, что запросы должны истечь по истечении максимум одного миллиарда секунд. Однако за один миллиард секунд до конечной даты в 2038 году приходится 01:27:28 UTC 13 мая 2006 года, поэтому запросы, отправленные после этого времени, приведут к дате истечения времени, выходящей за пределы предельного времени. Это привело к переполнению вычислений тайм-аута и возврату дат, которые на самом деле были в прошлом, что привело к сбою программного обеспечения. Когда проблема была обнаружена, операторам AOLServer пришлось отредактировать файл конфигурации и установить меньшее значение тайм-аута. [ 4 ] [ 5 ]
Решения
[ редактировать ]Универсального решения проблемы 2038 года не существует. Например, в языке C любое изменение определения time_t
тип данных может привести к проблемам совместимости кода в любом приложении, в котором представления даты и времени зависят от природы подписанного 32-битного файла. time_t
целое число. Например, изменение time_t
в беззнаковое 32-битное целое число, что расширит диапазон до 2106. [ 10 ] (в частности, 06:28:15 UTC в воскресенье, 7 февраля 2106 г.), отрицательно повлияет на программы, которые хранят, извлекают или манипулируют датами до 1970 года, поскольку такие даты представлены отрицательными числами. Увеличение размера time_t
тип до 64 бит в существующей системе приведет к несовместимым изменениям в расположении структур и двоичном интерфейсе функций.
Большинство операционных систем, предназначенных для работы на 64-битном оборудовании, уже используют подписанные 64-битные версии. time_t
целые числа. Использование 64-битного значения со знаком вводит новую дату цикла, которая более чем в двадцать раз превышает предполагаемый возраст Вселенной : примерно через 292 миллиарда лет. [ 11 ] Возможность производить вычисления по датам ограничена тем фактом, что tm_year
использует 32-битное целое число со знаком, начиная с 1900 года. Это ограничивает год максимумом в 2 147 485 547 (2 147 483 647 + 1900). [ 12 ]
Были сделаны альтернативные предложения (некоторые из которых уже используются), такие как хранение миллисекунд или микросекунд с начала эпохи (обычно 1 января 1970 года или 1 января 2000 года) в 64-битном целом со знаком, обеспечивающем минимальный диапазон 300 000. лет с микросекундным разрешением. [ 13 ] [ 14 ] В частности, повсеместное использование в Java 64-битных длинных целых чисел для представления времени в виде «миллисекунд с 1 января 1970 года» будет корректно работать в течение следующих 292 миллионов лет. Другие предложения по новым представлениям времени обеспечивают различную точность, диапазоны и размеры (почти всегда шире 32 бит), а также решают другие связанные проблемы, такие как обработка дополнительных секунд . В частности, ТАИ64 [ 15 ] представляет собой реализацию стандарта Международного атомного времени (TAI), текущего международного стандарта реального времени для определения секунды и системы отсчета.
Реализованные решения
[ редактировать ]- Начиная с версии Ruby 1.9.2 (выпущенной 18 августа 2010 г.) исправлена ошибка с 2038 годом. [ 16 ] сохраняя время в виде 64-битного целого числа со знаком в системах с 32-битным
time_t
. [ 17 ] - Начиная с версии NetBSD 6.0 (выпущенной в октябре 2012 г.), операционная система NetBSD использует 64-разрядную версию.
time_t
как для 32-битной, так и для 64-битной архитектуры. Приложения, скомпилированные для более старой версии NetBSD с 32-разрядной версией.time_t
поддерживаются через уровень двоичной совместимости, но такие старые приложения по-прежнему будут страдать от проблемы Y2038. [ 18 ] - OpenBSD , начиная с версии 5.5, выпущенной в мае 2014 года, также использует 64-битную версию.
time_t
как для 32-битной, так и для 64-битной архитектуры. В отличие от NetBSD здесь нет уровня двоичной совместимости. Поэтому приложения, ожидающие 32-разрядную версиюtime_t
и приложения, использующие что-либо отличное отtime_t
для хранения значений времени может сломаться. [ 19 ] - Linux изначально использовал 64-битную версию.
time_t
только для 64-битных архитектур; чистый 32-битный ABI не был изменен из-за обратной совместимости. [ 20 ] Начиная с версии 5.6 2020 года, 64-битнаяtime_t
поддерживается и на 32-битных архитектурах. Это было сделано в первую очередь ради встраиваемых систем Linux . [ 21 ] - Библиотека GNU C, начиная с версии 2.34 (выпущенной в августе 2021 г.), добавлена поддержка использования 64-битной версии.
time_t
на 32-битных платформах с соответствующими версиями Linux. Эту поддержку можно активировать, определив макрос препроцессора._TIME_BITS
к64
при компиляции исходного кода. [ 22 ] - FreeBSD использует 64-битную версию.
time_t
для всех 32-битных и 64-битных архитектур, кроме 32-битной i386, которая использует подписанные 32-битные архитектуры.time_t
вместо. [ 23 ] - x32 ABI для Linux (который определяет среду для программ с 32-битными адресами, но процессор работает в 64-битном режиме) использует 64-битный
time_t
. Поскольку это была новая среда, особых мер предосторожности в отношении совместимости не было. [ 20 ] - Сетевая файловая система версии 4 определила свои поля времени как
struct nfstime4 {int64_t seconds; uint32_t nseconds;}
с декабря 2000 года. [ 24 ] Версия 3 поддерживает 32-битные значения без знака, какstruct nfstime3 {uint32 seconds; uint32 nseconds;};
. [ 25 ] Значения больше нуля в поле секунд обозначают даты после 0 часов, 1 января 1970 года. Значения меньше нуля в поле секунд обозначают даты до 0 часов, 1 января 1970 года. В обоих случаях nсекунд (наносекунд ) поле должно быть добавлено к полю секунд для окончательного представления времени. - Файловая система ext4 при использовании с размером индексного дескриптора более 128 байт имеет дополнительное 32-битное поле на каждую временную метку, из которых 30 бит используются для наносекундной части временной метки, а остальные 2 бита используются для расширения диапазона временной метки. до 2446 года. [ 26 ]
- Файловая система XFS , начиная с Linux 5.10, имеет дополнительную функцию «больших временных меток», которая расширяет диапазон временных меток до 2486 года. [ 27 ]
- Хотя собственные API OpenVMS могут поддерживать временные метки до 31 июля 31086, [ 28 ] библиотека времени выполнения C (CRTL) использует 32-битные целые числа для
time_t
. [ 29 ] В рамках работы по обеспечению соответствия требованиям 2000 года, которая проводилась в 1998 году, CRTL был модифицирован для использования 32-битных целых чисел без знака для представления времени; расширение диапазонаtime_t
до 7 февраля 2106 г. [ 30 ] - PostgreSQL, начиная с версии 7.2, выпущенной 4 февраля 2002 г., хранит временную метку БЕЗ ЧАСОВОГО ПОЯСА как 64-битную. [ 31 ] [ не удалось пройти проверку ] Предыдущие версии уже сохраняли метку времени как 64-битную. [ нужна ссылка ]
- Начиная с версии MySQL 8.0.28, выпущенной в январе 2022 г., функции
FROM_UNIXTIME()
,UNIX_TIMESTAMP()
, иCONVERT_TZ()
обрабатывать 64-битные значения на платформах, которые их поддерживают. Сюда входят 64-разрядные версии Linux, macOS и Windows. [ 32 ] [ 33 ] В старых версиях встроенные функции, такие какUNIX_TIMESTAMP()
вернет 0 после 03:14:07 UTC 19 января 2038 года. [ 34 ]
См. также
[ редактировать ]- Ошибки форматирования и хранения времени перечисляет другие подобные проблемы, часто вызванные опрокидыванием, аналогичной причине этой проблемы 2038 года.
- Изменение номера недели GPS случайно произойдет позже в 2038 году, по другой причине, чем проблема 2038 года.
Примечания
[ редактировать ]- ^ Если не указано иное, все числа, представленные в этой статье, были получены с использованием дополнения до двух для арифметики целых чисел со знаком.
- ^ У GPS есть собственная проблема переполнения счетчика времени, известная как переворот номера недели GPS .
Ссылки
[ редактировать ]- ^ Jump up to: а б «Является ли проблема 2038 года новой ошибкой 2000 года?» . Хранитель . 17 декабря 2014 г. Архивировано из оригинала 25 января 2022 г. . Проверено 11 октября 2018 г.
- ^ Бергманн, Арнд (6 февраля 2020 г.). «Конец эпохи» . Линаро. Архивировано из оригинала 7 февраля 2020 года . Проверено 13 сентября 2020 г.
- ^ Вагенсейл, Пол (28 июля 2017 г.). «Цифровой «Эпокалипсис» может привести мир к полной остановке» . Путеводитель Тома . Архивировано из оригинала 29 ноября 2021 года . Проверено 13 сентября 2020 г.
- ^ Jump up to: а б «Будущее впереди» . 28 июня 2006 г. Архивировано из оригинала 28 ноября 2006 г. Проверено 19 ноября 2006 г.
- ^ Jump up to: а б Странная проблема с «утечкой памяти» в AOLserver 3.4.2/3.x. Архивировано 4 января 2010 г. на Wayback Machine, 12 мая 2006 г.
- ^ «Время Эпохи» . уникстутория . 15 марта 2019 года. Архивировано из оригинала 13 апреля 2023 года . Проверено 13 апреля 2023 г.
- ^ Диомидис Спинеллис (2006). Качество кода: взгляд на открытый исходный код . Серия эффективных разработок программного обеспечения в Safari Books Online (иллюстрированное издание). Adobe Пресс . п. 49. ИСБН 978-0-321-16607-4 .
- ^ «ZTE Blade под управлением Android 2.2 имеет 2038 проблем» . Архивировано из оригинала 19 мая 2022 года . Проверено 20 ноября 2018 г.
- ^ «Методы/процедуры испытаний ARB» . ARB.ca.gov . Калифорнийский совет по воздушным ресурсам . Архивировано из оригинала 18 ноября 2016 года . Проверено 12 сентября 2013 г.
- ^ «ПРОЕКТ: Проект прочности Y2038» . Архивировано из оригинала 21 сентября 2019 года . Проверено 25 мая 2024 г.
- ^ «Когда на самом деле заканчивается время time_t в 64-битной Unix?» . Архивировано из оригинала 23 сентября 2022 года . Проверено 24 сентября 2022 г.
- ^ Фелтс, Боб (17 апреля 2010 г.). «Конец времени» . Stablecross.com . Архивировано из оригинала 11 октября 2012 года . Проверено 19 марта 2012 г.
- ^ «Время Унунуниум» . Архивировано из оригинала 8 апреля 2006 года . Проверено 19 ноября 2006 г.
- ^ Сан Микросистемс. «Документация API Java для System.currentTimeMillis()» . Архивировано из оригинала 30 сентября 2017 года . Проверено 29 сентября 2017 г.
- ^ «ТАИ64» . Архивировано из оригинала 26 сентября 2012 года . Проверено 4 сентября 2012 г.
- ^ «Выпущен Ruby 1.9.2» . 18 августа 2010 г. Архивировано из оригинала 8 апреля 2022 г. Проверено 1 апреля 2022 г.
- ^ «time.c: используйте 64-битную арифметику даже на платформах с 32-битной VALUE» . Гитхаб . Архивировано из оригинала 3 ноября 2023 года . Проверено 3 ноября 2023 г.
- ^ «Анонс NetBSD 6.0» . 17 октября 2012 года. Архивировано из оригинала 15 января 2016 года . Проверено 18 января 2016 г.
- ^ «Выпущена OpenBSD 5.5 (1 мая 2014 г.)» . 1 мая 2014 года. Архивировано из оригинала 22 декабря 2015 года . Проверено 18 января 2016 г.
- ^ Jump up to: а б Джонатан Корбет (14 августа 2013 г.). «Размышляя о 2038 году» . LWN.net . Архивировано из оригинала 4 марта 2016 года . Проверено 9 марта 2016 г.
- ^ «LKML: Арнд Бергманн: [GIT PULL] y2038: изменения ядра, драйверов и файловой системы» . lkml.org . Архивировано из оригинала 14 февраля 2020 года . Проверено 30 января 2020 г.
- ^ О'Донелл, Карлос (2 августа 2021 г.). «Библиотека GNU C версии 2.34 теперь доступна» . Исходное программное обеспечение . Архивировано из оригинала 30 апреля 2024 года . Проверено 30 апреля 2024 г.
- ^ «арка» . www.freebsd.org . Архивировано из оригинала 26 сентября 2018 года . Проверено 26 сентября 2018 г.
- ^ Хейнс, Томас; Новек, Дэвид, ред. (март 2015 г.). «Структурированные типы данных» . Протокол сетевой файловой системы (NFS) версии 4 . сек. 2.2. дои : 10.17487/RFC7530 . РФК 7530 .
- ^ Штаубах, Питер; Павловски, Брайан; Каллаган, Брент (июнь 1995 г.). «Спецификация протокола NFS версии 3» . Проверено 25 мая 2024 г.
- ^ «Структуры данных и алгоритмы ext4» . Архивировано из оригинала 13 сентября 2022 года . Проверено 13 сентября 2022 г.
- ^ Майкл Ларабель (15 октября 2020 г.). «Файловая система XFS с Linux 5.10 Punts от 2038 года до 2486 года» . Фороникс . Архивировано из оригинала 13 сентября 2022 года . Проверено 13 сентября 2022 г.
- ^ «Почему среда, 17 ноября 1858 года, является базовым временем для OpenVMS (VAX VMS)?» . Стэнфордский университет . 24 июля 1997 года. Архивировано из оригинала 24 июля 1997 года . Проверено 8 января 2020 г.
- ^ «Справочное руководство по библиотеке времени выполнения VSI C для систем OpenVMS» (PDF) . ВСИ. Ноябрь 2020 г. Архивировано из оригинала (PDF) 17 апреля 2021 г. . Проверено 17 апреля 2021 г.
- ^ «OpenVMS и 2038 год» . ХП. Архивировано из оригинала 17 апреля 2021 года . Проверено 17 апреля 2021 г.
- ^ «PostgreSQL версии 7.2» . Январь 2012. Архивировано из оригинала 26 апреля 2024 года . Проверено 25 апреля 2024 г.
- ^ «Что нового в MySQL 8.0» . dev.mysql.com .
- ^ «Изменения в MySQL 8.0.28 (18 января 2022 г., общедоступная версия)» . dev.mysql.com . Архивировано из оригинала 8 декабря 2023 года . Проверено 14 мая 2024 г.
- ^ «Ошибки MySQL: № 12654: 64-битная временная метка Unix не поддерживается в функциях MySQL» . bugs.mysql.com . Архивировано из оригинала 29 марта 2017 года . Проверено 28 марта 2017 г.
Внешние ссылки
[ редактировать ]- Y2038 Proofness Design glibc вики
- Статья о том, как все работает
- Часто задаваемые вопросы по проекту 2038
- Критические и знаменательные даты 2038 года
- Безопасная для 2038 замена time.h в 32-битных системах.
- «Решение проблемы 2038 года в ядре Linux» .
- Баранюк, Крис (5 мая 2015 г.). «Номерной сбой, который может привести к катастрофе» . BBC Будущее .
- Клеветт, Джеймс. «2 147 483 647 – Конец времени [Unix]» . Числофил . Брэйди Харан . Архивировано из оригинала 22 мая 2017 года . Проверено 7 апреля 2013 г.