Utilo

Unix Time Stamp Explained: секунды, миллисекунды, часовые пояса и 2038

Что такое время в Unix, почему системы используют его, как конвертировать временные метки на всех основных языках, и как избежать ошибок часового пояса, миллисекунд и Y2038.

· 4 мин чтения

Откройте практически любой файл журнала, таблицу базы данных или ответ API, и вы найдете такие номера, как 1760000000. Это часовой знак Unix: количество секунд, прошедших с 00:00:00 UTC 1 января 1970 года, известный как эпоха Unix. Это наиболее распространенный способ, которым компьютеры представляют момент во времени, и понимание этого предотвращает целый класс ошибок, связанных с часовыми поясами, летним временем и анализами дат.

Зачем считать секунды с 1970 года?

Ранние разработчики Unix нуждались в простом, компактном представлении времени. Подсчет секунд от фиксированной недавней даты вписывался в одно целое число, легко сравнивался и вычитался, и избегал сложности календарей. Дата 1 января 1970 года была просто удобной отправной точкой, когда создавался Unix.

Преимущества сохраняются и сегодня:

  • Независимо от часового пояса. Временная метка идентифицирует момент, а не настенные часы. То же самое событие имеет одинаковую дату в Токио, Берлине и Сан-Паулу.
  • Простая арифметика. Разница между двумя временными метками - длительность в секундах. Добавить 86 400 движений вперед за один день.
  • Компактный и сортируемый. Целое число занимает 8 байтов и сортируется хронологически.
  • Недвусмысленно. Не путать 03/04 с 4 марта или 3 апреля.

Секунды против миллисекунд

Наиболее распространенная ошибка с временной меткой - смешивание единиц:

  • Инструменты Unix, большинство баз данных, JWT и многие API используют секунды: 10 цифр сегодня, например 1760000000.
  • Date.now() JavaScript, System.currentTimeMillis() Java и многие аналитические системы используют ** миллисекунды**: 13 цифр, например 1760000000000.
  • Некоторые системы используют микросекунды (16 цифр) или наносекунды (19 цифр).

Если интерпретировать миллисекунды как секунды, то мы получим дату в десятки тысяч лет в будущем; обратный вариант приводит к январю 1970 года. Если вы когда-нибудь увидите "1970-01-21" в пользовательском интерфейсе, кто-то прошел секунды, где ожидалось миллисекунды. [преобразователь часовой метки](/инструменты/годовой метка) определяет длину единицы, что является быстрой проверкой здравомыслия.

Преобразование часовых меток на общие языки

JavaScript

const nowSeconds = Math.floor(Date.now() / 1000);
const date = new Date(1760000000 * 1000);
date.toISOString(); // "2025-10-09T08:53:20.000Z"

Питон.

import time, datetime
now = int(time.time())
dt = datetime.datetime.fromtimestamp(1760000000, tz=datetime.timezone.utc)

Всегда передавайте tz= в Python; без него fromtimestamp возвращает наивное местное время, которое легко неправильно интерпретировать.

**SQL (PostgreSQL) **

SELECT to_timestamp(1760000000);           -- timestamptz
SELECT extract(epoch FROM now())::bigint;  -- current Unix time

Иди.

t := time.Unix(1760000000, 0).UTC()
now := time.Now().Unix()

Оболочка

date +%s                    # current timestamp
date -u -d @1760000000      # GNU date
date -u -r 1760000000       # macOS/BSD date

Часовые пояса: хранить UTC, отображать локальные

Временная метка не имеет часового пояса; это абсолютный момент. Возникают проблемы при преобразовании в читаемые человеком даты:

  • Парсировка даты без зоны. new Date("2026-03-29 02:30") интерпретируется в местном часовом поясе той машины, на которой запускается код. На сервере в UTC и ноутбуке в Берлине он производит разные временные отметки.
  • Разрывы и перекрытия по летнему времени. В зонах с ДНС некоторые местные часы не существуют (часы прыгают вперед), а другие появляются дважды (часы возвращаются назад). Время не имеет такой неоднозначности.
  • Если вы сохраните "2026-11-01 01:30" без зоны, вы никогда не сможете быть уверены, в какой момент это было.

Правило: хранить и передавать часовые метки или строки ISO 8601 с явным смещением (2026-10-11T09:30:00Z или +02:00). Преобразование в локальную зону пользователя только при отображении. Сохраняйте имя часового пояса пользователя IANA (например, Europe/Berlin) отдельно, если вам нужно запланировать вещи в местное время.

ISO 8601 против Unix временных меток

Строки ISO 8601, такие как 2026-10-11T09:30:00Z, читаются человеком и также недвусмысленны, когда они включают Z или смещение. Многие API предпочитают их для четкости. Временные метки Unix меньше и быстрее сравнивать. Оба варианта хороши; главное - последовательность и всегда включая информацию о зонах.

Преломные секунды

Земное вращение слегка нерегулярно, поэтому официальный UTC иногда вставляет високосную секунду. Время Unix игнорирует их: каждый день составляет ровно 86 400 секунд, и в течение високосной секунды временная метка повторяется или стирается. Для почти всех приложений это невидимо. Если вы работаете с высокой точностью времени, используйте время TAI или GPS. Международные органы по измерению времени решили постепенно отменить перерывные секунды к 2035 году, что сделает это еще менее тревожным.

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

Многие более старые системы хранят время Unix в виде подписанного 32-битного целого числа, максимальное значение которого составляет 2,147,483,647. Это соответствует 03:14:07 UTC 19 января 2038 года. Через секунду значение переполняется до −2,147,483,648, что соответствует 13 декабря 1901 года.

Современные 64-разрядные операционные системы, языки и базы данных используют 64-разрядные временные метки, которые не будут переполняться около 292 миллиардов лет. Риски сохраняются:

  • Встроенные устройства и промышленные контроллеры с длительным сроком службы.
  • Форматы файлов и сетевые протоколы с 32-разрядными временными полями.
  • Колонки базы данных, объявленные как 32-битные INT с эпоховыми секундами. Тип TIMESTAMP в MySQL имеет лимит 2038; DATETIME или BIGINT нет.

Проверяйте долгоживущие данные сейчас, особенно все, что хранит будущие даты, такие как срок действия сертификата или 20-летние контракты.

Отрицательные временные отметки

Даты до 1970 года имеют отрицательные временные отметки. -86400 31 декабря 1969 года. Большинство современных языков обрабатывают их правильно, но некоторые старые API и электронные таблицы этого не делают, поэтому проверяйте исторические даты явно.

Практический контрольный список отладки

  1. Подсчитайте цифры: 10 для секунд, 13 для миллисекунд.
  2. Преобразуйте в UTC сначала, затем в местное время, чтобы отделить блочные ошибки от зональных ошибок.
  3. Проверьте, включает ли строка даты Z или смещение, прежде чем проанализировать ее.
  4. Сравните часы сервера и клиента, если токены или подписи не выполняются с ошибками "прошел срок действия" или "пока не действителен" см. как работает JWT для того, почему exp и nbf являются Unix-секундами.
  5. При планировании повторяющихся задач помните, что cron работает в зоне сервера; эти примеры cron охватывают детали.

Итоги

Временный штемпель Unix - это количество секунд с 1970-01-01 UTC. Он прост, независим от часовых поясов и легко вычисляется. Большинство ошибок происходит от смешивания секунд и миллисекунд, анализа дат без зон или хранения местного времени. Сохраняйте UTC, конвертируйте на краях, используйте 64-разрядные целые числа, и вам редко придется снова думать о времени.

Эта страница переведена с английского автоматически. Если вы заметили ошибку, сообщите нам.

Похожие руководства