Что такое проблема 2038 года
Проблема 2038 года (также известная как Y2K38 или «тысячелетний баг Unix») — это проблема переполнения даты, затрагивающая системы, хранящие Unix-метки времени как знаковое 32-битное целое число. Максимальное значение знакового 32-битного целого — 2 147 483 647, что соответствует 03:14:07 UTC 19 января 2038 года. Через секунду счётчик переполняется до наименьшего (наиболее отрицательного) 32-битного значения, соответствующего 13 декабря 1901 года, что вызывает катастрофические ошибки дат.
Почему это происходит
Знаковое 32-битное целое может хранить значения от -2 147 483 648 до 2 147 483 647. Когда в начале 1970-х годов проектировались Unix-метки времени, 2038 год казался немыслимо далёким. Но встроенные системы, базы данных и унаследованный код, написанные тогда, продолжают работать и сегодня.
Какие системы под угрозой
- Встроенные системы: промышленные контроллеры, маршрутизаторы и IoT-устройства, использующие 32-битный
time_tв C - Устаревшие базы данных: столбцы
TIMESTAMPв MySQL (диапазон: 1970–2038) - Старые ядра Linux: 32-битные системы Linux, использующие
time_tкак знаковое 32-битное целое - Файловые системы: некоторые форматы файлов хранят время изменения в 32-битных полях
- Финансовое ПО: любая система, планирующая события после 19 января 2038 года
Решение: использовать 64-битные метки времени
Знаковое 64-битное целое может представлять метки времени вплоть до 292 277 026 596 года — с огромным запасом сверх любых практических опасений. Большинство современных систем уже используют 64-битное время:
# Python — uses 64-bit internally, safe
import time
print(time.time()) # works past 2038
# C — use int64_t or time64_t instead of time_t on 32-bit systems
#include <stdint.h>
int64_t ts = (int64_t)time(NULL);
# MySQL — use DATETIME (range: 1000–9999) instead of TIMESTAMP
ALTER TABLE events MODIFY created_at DATETIME NOT NULL;
Текущее состояние
- 64-битные системы Linux (подавляющее большинство сегодня) в безопасности — на 64-битных платформах
time_tимеет 64 бита. - MySQL 8.0.28+ расширил TIMESTAMP для поддержки дат после 2038 года в некоторых конфигурациях.
- В ядре Linux 5.6 (2020) была исправлена проблема 32-битного
time_tдля 32-битных платформ. - Миллиарды 32-битных встроенных устройств остаются уязвимыми и, возможно, никогда не будут обновлены.
Что нужно сделать уже сегодня
Проверьте все системы, которые планируют или хранят даты после января 2038 года. Перенесите столбцы баз данных TIMESTAMP на DATETIME или BIGINT. Убедитесь, что весь 32-битный встроенный код использует 64-битные библиотеки времени. Проблема полностью решаема — но только если действовать до наступления критической даты.