Вы, вероятно, помните панику, связанную с проблемой Y2K. СМИ с удовольствием предсказывали глобальный коллапс, когда часы пробили 2000 год. Но в то время как многие устаревшие системы были тогда «затянуты», в фоне значительной части современного интернета продолжает тикать другой таймер. Он называется проблема 2038 года. И она коренится в том, как языки программирования C обрабатывают время.

Большинство людей ошибочно полагают, что проблема связана с двухзначными годами, как в случае с Y2K. На самом деле это не так. Корень проблемы лежит глубже в коде. А именно — в том, как программы на C хранят данные о дате.

Ограничение 32-битной архитектуры

Вот техническая реальность. Стандартная библиотека времени в C использует 4-байтовое знаковое целое число для отслеживания времени. Это 32 бита. Этот формат определяет «эпохальное время» (epoch time), начиная с 1 января 1970 года в 00:00:00 по UTC. Каждая секунда после этого момента сохраняется как простое число.

Например, метка времени 919642718 представляет собой 919 миллионов секунд, прошедших с начала эпохи. Это соответствует 21 февраля 1999 года. Это удобно, потому что вычитание одной метки времени из другой дает точное количество секунд между двумя событиями. Библиотеки затем преобразуют эти секунды в минуты, часы или годы.

Но существует жесткий предел.

Максимальное значение знакового 32-битного целого числа равно 2 147 483 647. Как только этот счетчик достигает нуля секунд после 1 января 1970 года, происходит переполнение (переход через ноль).

Это переполнение происходит 19 января 2038 года.

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

Почему это проще, чем проблема Y2K

Хорошая новость? Исправление этой проблемы не так грязно, как кошмары с мейнфреймами конца 90-х.

В случае с Y2K многие системы не стандартизировали способ хранения дат. Некоторые использовали формат ММ-ДД-ГГ. Другие — ГГ-ММ-ДД. Отсутствие универсального формата означало, что разработчикам приходилось искать код в каждом приложении и вручную изменять логику работы с датами.

Проблема 2038 года чище.

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

Например, переход от 4-байтового целого числа к 8-байтовому значительно расширяет диапазон. Знаковое 8-байтовое целое число может считать далеко за пределы 2038 года без переполнения. Это программное обновление. Не замена оборудования. Не переписывание кода. Просто замена библиотеки.

Windows и Mac: разные таймеры, разные проблемы

Не все системы используют 32-битный формат C. Различные операционные системы имеют свои особенности.

Windows NT, например, использует 64-битное целое число. Она отслеживает время с шагом в 100 наносекунд. Но отсчет начинается не с 1970 года, а с 1 января 1601 года. Это отодвигает дату переполнения гораздо дальше. Вероятно, Windows достигнет своего предела примерно в 2184 году.

Apple пошла другим путем. Согласно официальной документации Apple, macOS спроектирована так, чтобы оставаться корректной до 29 940 года. Это примерно 27 000 лет отныне. Так что, если вы используете Mac, вам не нужно беспокоиться о том, что ваш календарь «сломается» в 2038 году.

Кто еще в зоне риска?

Основную опасность представляют системы на базе Unix. Но они не одиноки.

Встроенные системы (embedded systems) также уязвимы. Многие устройства IoT, промышленные контроллеры и старые серверы баз данных полагаются на тот же 32-битный формат времени. Если они не были обновлены, они начнут неверно интерпретировать даты после 19 января 2038 года.

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

Вопрос не в том, сломается ли код. Вопрос в том, будут ли обновлены системы, на которых этот код работает, до того, как время истечет.

Большая часть инфраструктуры, на которую мы полагаемся, уже переходит на 64-битный учет времени. Но не вся. Старые серверы. Устаревшее промышленное оборудование. Некоторые встроенные логики. Это слабые звенья.

Когда наступит 19 января 2038 года, часы достигнут своего предела. Для некоторых систем это будет незаметным событием. Для других — жестким остановом. Если вы будете ждать до последней минуты, у вас не останется много времени на патчинг кода.