Почему Unix-время начинается 1 января 1970 года

Дата 1970-01-01 00:00:00 UTC стала общей точкой координат для Unix-подобных систем, языков программирования и множества форматов данных. Она не обозначает начало компьютерной эры и не появилась в готовом виде вместе с первой версией Unix: прежде чем разработчики остановились на знакомой нам схеме, единицы измерения и сама эпоха менялись несколько раз.
У первого Unix была другая эпоха
В руководстве первой редакции Unix, датированном ноябрём 1971 года, системный вызов time возвращал 32-битное количество шестидесятых долей секунды, прошедших с 1 января 1971 года. Такая частота соответствовала системным часам PDP-11, но быстро обнаружила неприятное ограничение: 32 бит хватало лишь примерно на два с половиной года.
Чтобы счётчик не закончился, ранние разработчики Unix несколько раз переносили его начало и поправляли даты уже существующих файлов. В 1973 году они выбрали более долговечную схему: стали хранить целые секунды от начала 1970 года. Переход от 60 тиков к одной секунде сразу увеличил доступный диапазон примерно в 60 раз, а новая эпоха находилась достаточно близко к текущим для системы датам.
Исторические материалы хорошо фиксируют последовательность этих изменений, но не дают оснований превращать 1 января 1970 года в символическую дату или приписывать ей сложную философию. Это было практическое инженерное решение, которое пережило исходное оборудование, закрепилось в системных интерфейсах и стало дорогим для замены после распространения Unix.
Что именно считает Unix timestamp
В современном POSIX эпохой называется полночь 1 января 1970 года по UTC, а значение времени приближённо выражает количество секунд после этой точки. Слово «приближённо» здесь важно: формула POSIX отводит каждому календарному дню ровно 86 400 секунд и не превращает timestamp в непрерывный счёт всех физических секунд с учётом вставок leap second.
Сам timestamp также не содержит часовой пояс. Число 0 обозначает один и тот же момент, но локальное представление может показать вечер 31 декабря 1969 года к западу от Гринвича или утро 1 января 1970 года к востоку от него. Поэтому при обмене датами важно передавать зону явно, а для однозначного машинного значения обычно используют UTC.
Строго говоря, Unix timestamp измеряется в секундах. Числа в миллисекундах, микросекундах и наносекундах являются распространёнными расширениями того же принципа, поэтому единицу нельзя угадывать только по названию поля. Значение 1700000000 похоже на секунды, а 1700000000000 на миллисекунды, однако надёжный формат данных должен сообщать это явно.
Откуда берётся проблема 2038 года
Знаковое 32-битное целое хранит значения от −2 147 483 648 до 2 147 483 647. Если такое поле содержит секунды после Unix epoch, его последнее положительное значение соответствует 2038-01-19 03:14:07 UTC; уже момент 03:14:08 представить в этом формате невозможно.
Отсюда и знакомая иллюстрация Y2038: при обычном двухкомплементарном переносе битовый шаблон следующего значения читается как −2 147 483 648 и указывает на 1901-12-13 20:45:52 UTC. Однако это не означает, что каждое устройство ровно в эту секунду покажет 1901 год. В зависимости от языка, библиотеки и операции программа может получить ошибку переполнения, неверно отсортировать даты, зациклить таймер или сломаться иным способом. Руководство Linux для time() поэтому формулирует практическое требование прямо: приложениям, рассчитанным на работу после 2038 года, нужен ABI с time_t шире 32 бит.

Проблема может проявиться и раньше самой даты. Ипотечный расчёт, сертификат, бронь, срок хранения данных или задача планировщика уже сегодня способны обратиться к моменту после границы. Если один из компонентов цепочки обрезает значение до 32 бит, ошибка возникает при записи или обработке будущей даты, а не только в январе 2038 года.
Почему переход на 64 бита не заканчивается заменой типа
В новом совместимом с POSIX.1-2024 окружении time_t должен иметь ширину не менее 64 бит. Этого диапазона с огромным запасом хватает для любых практических календарных задач, но наличие 64-битного процессора само по себе ничего не доказывает: важно, какой ABI использует конкретная программа и как время проходит через все внешние границы.
Например, 32-битный Linux может предоставить 64-битные системные вызовы времени, а C-библиотека передаст их приложению через time64-интерфейс. В glibc для традиционных 32-битных платформ предусмотрена конфигурация _TIME_BITS=64, меняющая ширину time_t и связанных функций. Старый уже собранный бинарник при этом не переписывается, как не меняются автоматически 32-битные поля в базе данных, структуре файла, сетевом пакете или микропрограмме устройства.
Поэтому проверка на Y2038 состоит не в поиске любого 32-битного оборудования, а в прослеживании полного маршрута даты. Нужно проверить системные и библиотечные интерфейсы, сериализацию, схему хранилища и граничные значения в бизнес-логике. Особенно полезны тесты на 2038-01-19 03:14:07 UTC, следующую секунду и даты заметно дальше в будущем: они показывают не только явное переполнение, но и скрытое усечение при преобразовании между форматами.
Как пользоваться Epoch Counter
Epoch Counter собирает повседневные операции с Unix-временем в одном локальном инструменте. Живой счётчик показывает текущий момент в секундах, миллисекундах, микросекундах и наносекундах; два последних значения честно отмечены как имеющие миллисекундную точность, поскольку браузер не получает из системных часов дополнительные разряды простым дописыванием нулей.
Конвертер автоматически предполагает единицу по длине введённого числа и принимает секунды, миллисекунды, микросекунды или наносекунды. Результат можно посмотреть в UTC или локальном времени, в человекочитаемом и ISO 8601 представлении. Обратное преобразование принимает несколько распространённых форматов даты, причём Z или GMT обозначают UTC, а строка без зоны разбирается как локальное время браузера.
Отдельные панели находят начало и конец дня, месяца или года, переводят количество секунд в длительность и показывают готовые операции для двенадцати языков и СУБД, включая JavaScript, Python, PHP, Go, Rust, PostgreSQL и Shell. Все вычисления происходят в браузере, но очень большие значения всё равно ограничены диапазоном и числовой точностью JavaScript Date, поэтому инструмент подходит для прикладных дат, а не для арифметики произвольной разрядности.
Для быстрой проверки введите 2147483647 как секунды и убедитесь, что получается 2038-01-19 03:14:07 UTC. Затем прибавьте единицу: Epoch Counter на современном браузере продолжит считать дату корректно, наглядно показывая, что граница принадлежит старому 32-битному формату хранения, а не самому календарю или Unix epoch.
Похожие инструменты
Частые вопросы
Почему Unix-время начинается с 1 января 1970 года?
Это не была первая эпоха Unix. В руководстве первой редакции системы время отсчитывалось от 1 января 1971 года в шестидесятых долях секунды, а после нескольких переносов точки отсчёта в 1973 году разработчики перешли к целым секундам от 1 января 1970 года. Источники хорошо описывают эту техническую эволюцию, но не подтверждают популярную историю о единственном почти случайном выборе даты.
Что произойдёт 19 января 2038 года?
В 03:14:07 UTC знаковое 32-битное поле секунд достигает значения 2 147 483 647. Следующая секунда в нём уже не помещается. При интерпретации переполненного двухкомплементарного значения как −2 147 483 648 получится 13 декабря 1901 года, но реальная программа может также вернуть ошибку, неверно сравнить даты или завершиться сбоем. Поведение зависит от конкретной системы.
Все ли 32-битные системы подвержены проблеме 2038 года?
Нет. Опасность определяется шириной временного типа и всего пути данных, а не только разрядностью процессора. 32-битная система может использовать 64-битный time_t и интерфейсы time64, тогда как старый бинарник, формат файла или сетевой протокол с 32-битным полем времени останется ограниченным даже на новом оборудовании.
Решена ли проблема 2038 года?
Для новых POSIX-окружений и большинства 64-битных систем практическое ограничение снято переходом на time_t шириной не менее 64 бит. В старых 32-битных ABI нужны поддержка time64 в ядре и C-библиотеке, правильная конфигурация при сборке приложения, а иногда ещё миграция баз данных, файловых форматов и протоколов.
Учитывает ли Unix timestamp високосные секунды?
Обычное POSIX-время не ведёт непрерывный счёт атомных секунд: стандарт отводит каждому календарному дню ровно 86 400 секунд, а связь системного значения с фактическим UTC во время корректировок оставляет реализации. Поэтому Unix timestamp удобен для обмена моментами времени, но не заменяет специализированные шкалы для точных научных измерений.
Автор
Alex RelFullstack Engineer
В коммерческой разработке с 2011 года — больше 15 лет. Автор двух SaaS-продуктов: TeleGo.io и LingvoHabit.com. Статьи здесь выросли из реальной клиентской и продуктовой работы.



