В базе данных вместо даты записано 1791363600, в ответе API — 1791363600000, а в логе сервера — время на три часа раньше московского. Всё это проявления одной системы — Unix-времени. Разберём, как его читать, переводить и не ошибаться с часовыми поясами.
Что такое Unix-время
Unix-время (Unix timestamp, POSIX time, epoch time) — количество секунд, прошедших с 1 января 1970 года, 00:00:00 UTC (эта точка называется Unix epoch).
Преимущества:
- одно число вместо даты, времени и пояса;
- легко сравнивать и вычитать: разница двух timestamp — это интервал в секундах;
- не зависит от часового пояса, языка и формата записи даты.
Примеры:
| Timestamp | Дата и время (UTC) |
|---|---|
0 |
1 января 1970, 00:00:00 |
1000000000 |
9 сентября 2001, 01:46:40 |
1791363600 |
7 октября 2026, 09:00:00 |
2000000000 |
18 мая 2033, 03:33:20 |
2147483647 |
19 января 2038, 03:14:07 |
Перевести любое число в дату и обратно можно в конвертере Unix-времени.
Секунды или миллисекунды
Главный источник ошибок — разные единицы:
- секунды (10 цифр для дат с 2001 по 2286 год): Unix, PHP
time(), Pythontime.time()(дробное), MySQLUNIX_TIMESTAMP(); - миллисекунды (13 цифр): JavaScript
Date.now(), JavaSystem.currentTimeMillis(); - микро- и наносекунды (16 и 19 цифр): некоторые базы данных и системы логирования.
Если после преобразования получился 1970 год — вы, скорее всего, передали секунды туда, где ждали миллисекунды. Если год 55000-й — наоборот.
// JavaScript: миллисекунды
const ms = Date.now(); // 1791363600000
const sec = Math.floor(ms / 1000); // 1791363600
new Date(sec * 1000).toISOString(); // "2026-10-07T09:00:00.000Z"
# Python: секунды
from datetime import datetime, timezone
datetime.fromtimestamp(1791363600, tz=timezone.utc)
# 2026-10-07 09:00:00+00:00
Часовые пояса
Timestamp обозначает момент, а не «время на часах». Одно и то же число 1791363600 — это:
- 09:00 по UTC (в Лондоне 7 октября ещё действует летнее время, поэтому на местных часах — 10:00);
- 12:00 в Москве (UTC+3);
- 19:00 во Владивостоке (UTC+10).
Правила хорошего тона:
- храните время в UTC или как timestamp;
- преобразуйте в местное время только при показе пользователю;
- указывайте пояс явно в текстовых форматах:
2026-10-07T12:00:00+03:00.
Логи сервера, который показывает время «на три часа раньше», обычно просто пишут в UTC. Об устройстве поясов — в гайде Часовые пояса, а пересчитать время между городами поможет конвертер часовых поясов.
Проблема 2038 года
Во многих старых системах timestamp хранился в знаковом 32-битном целом (int32). Максимальное значение — 2 147 483 647, что соответствует 19 января 2038 года, 03:14:07 UTC. Следующая секунда переполнит счётчик, и время «перескочит» в 13 декабря 1901 года.
Кого это касается:
- встроенные системы и старое оборудование;
- программы на C с 32-битным
time_t; - столбцы
INTв базах данных, где хранится timestamp; - старые форматы файлов.
Современные 64-битные системы хранят время в 64 битах — этого хватит на сотни миллиардов лет. Если вы проектируете базу данных, используйте BIGINT или специальные типы даты и времени, а не INT. В MySQL тип TIMESTAMP ограничен 2038 годом, а DATETIME — нет.
Високосные секунды
Иногда к суткам добавляли високосную секунду, чтобы согласовать атомное время с вращением Земли. Unix-время их не учитывает: в нём каждые сутки ровно 86 400 секунд. Поэтому вычесть два timestamp и разделить на 86 400 — корректный способ получить число суток. В 2022 году Генеральная конференция по мерам и весам решила отказаться от високосных секунд к 2035 году.
Cron: расписание задач
Unix-время часто встречается рядом с cron — планировщиком задач в Unix-системах. Строка cron состоит из пяти полей:
┌──────── минута (0–59)
│ ┌────── час (0–23)
│ │ ┌──── день месяца (1–31)
│ │ │ ┌── месяц (1–12)
│ │ │ │ ┌ день недели (0–7, 0 и 7 — воскресенье)
│ │ │ │ │
*/15 * * * * — каждые 15 минут
0 3 * * * — каждый день в 03:00
30 9 * * 1-5 — по будням в 09:30
0 0 1 * * — в полночь первого числа месяца
Важно: cron использует часовой пояс сервера. Если сервер работает в UTC, задача «в 03:00» запустится в 06:00 по Москве. Составить выражение и проверить расписание можно в генераторе cron.
Unix-время в базах данных и Excel
- PostgreSQL:
to_timestamp(1791363600)преобразует число в дату,extract(epoch from now())— обратно. - MySQL:
FROM_UNIXTIME(1791363600)иUNIX_TIMESTAMP(). - Excel и Google Таблицы: даты хранятся как число дней с 1900 года, поэтому timestamp нужно перевести:
=A1/86400 + ДАТА(1970;1;1)(в англоязычной версии —DATE(1970,1,1)), а затем при необходимости прибавить 3/24 для московского времени.
Командная строка Linux тоже умеет работать с timestamp: date +%s выводит текущее время, а date -d @1791363600 — дату по числу (в macOS — date -r 1791363600).
ISO 8601 вместо timestamp
Если данные будет читать человек, удобнее формат ISO 8601: 2026-10-07T12:00:00+03:00. Он однозначен, сортируется как строка и содержит смещение пояса. В API часто используют оба формата: timestamp для расчётов и ISO 8601 для отображения и логов.
Частые ошибки
- Путать секунды и миллисекунды — даты 1970 года или далёкого будущего.
- Хранить локальное время без пояса — после переезда сервера или смены пояса данные смешиваются.
- Использовать 32-битные поля для дат после 2038 года (например, сроков ипотеки или подписок).
- Считать месяцы по 30 дней — для календарных расчётов используйте библиотеки дат. Подробнее — в гайде Как посчитать дни между датами.
Чек-лист
- Понятно, в каких единицах хранится timestamp.
- Время хранится в UTC, пояс применяется при показе.
- Поля в базе — 64-битные или специальные типы даты.
- Расписание cron составлено с учётом пояса сервера.