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 и электронные таблицы этого не делают, поэтому проверяйте исторические даты явно.
Практический контрольный список отладки
- Подсчитайте цифры: 10 для секунд, 13 для миллисекунд.
- Преобразуйте в UTC сначала, затем в местное время, чтобы отделить блочные ошибки от зональных ошибок.
- Проверьте, включает ли строка даты
Zили смещение, прежде чем проанализировать ее. - Сравните часы сервера и клиента, если токены или подписи не выполняются с ошибками "прошел срок действия" или "пока не действителен" см. как работает JWT для того, почему
expиnbfявляются Unix-секундами. - При планировании повторяющихся задач помните, что cron работает в зоне сервера; эти примеры cron охватывают детали.
Итоги
Временный штемпель Unix - это количество секунд с 1970-01-01 UTC. Он прост, независим от часовых поясов и легко вычисляется. Большинство ошибок происходит от смешивания секунд и миллисекунд, анализа дат без зон или хранения местного времени. Сохраняйте UTC, конвертируйте на краях, используйте 64-разрядные целые числа, и вам редко придется снова думать о времени.
Эта страница переведена с английского автоматически. Если вы заметили ошибку, сообщите нам.