Полное руководство по Unix timestamp: конвертация секунд/миллисекунд/микросекунд и работа с часовыми поясами
Unix timestamp представляет время как «количество секунд, прошедших с момента начала эпохи Unix (1 января 1970 года, 00:00:00 UTC)». Свыше 95 % веб-серверов и около 90 % систем баз данных по всему миру используют это представление внутри. В этом руководстве рассмотрены различия в точности, реализации в разных языках программирования, обработка часовых поясов и нюансы летнего времени.
Происхождение и определение Unix timestamp
Эпоха Unix началась 1 января 1970 года в 00:00:00 UTC. Unix timestamp 0 соответствует этому моменту, а 1262304000 — это 1 января 2010 года, 00:00:00 UTC. По умолчанию система игнорирует влияние високосных секунд.
Изначально timestamp хранился как 32-битное знаковое целое — отсюда родилась проблема 2038 года: максимальное значение переполняется 19 января 2038 года в 03:14:07 UTC. Современные системы используют 64-битные целые, что существенно расширяет представимые временные диапазоны.
Различия в точности времени
| Единица | Количество в секунде | Цифр | Типичные применения |
|---|---|---|---|
| Секунды (s) | 1 | 10 | Традиционные системы Unix/Linux |
| Миллисекунды (ms) | 1000 | 13 | JavaScript, Java, логирование |
| Микросекунды (μs) | 1 000 000 | 16 | Распределённый трейсинг, базы данных |
| Наносекунды (ns) | 1 000 000 000 | 19 | Язык Go, анализ производительности |
Практическое правило: 10-значный timestamp обычно означает секунды, 13 цифр — миллисекунды, 16 цифр — микросекунды, 19 цифр — наносекунды.
JavaScript
JavaScript нативно работает с миллисекундами. Конструктор Date() считает, что входное число — это миллисекунды; для timestamp в секундах умножайте на 1000.
// Получить текущий Unix timestamp (в миллисекундах)
const timestampMs = Date.now();
console.log(timestampMs); // Пример: 1692268800123
// Для timestamp в секундах поделите миллисекунды на 1000 и округлите вниз
const timestampSec = Math.floor(Date.now() / 1000);
console.log(timestampSec); // Пример: 1692268800
// Преобразовать Unix timestamp обратно в объект Date
let ts = 1692268800;
let date = new Date(ts * 1000);
console.log(date.toISOString()); // "2023-08-17T16:00:00.000Z"
Python
Функция time.time() возвращает Unix timestamp в секундах в виде числа с плавающей точкой:
import time
from datetime import datetime, timezone
# Текущий Unix timestamp (секунды, float)
now_sec = time.time()
print(now_sec) # Пример: 1692268800.123456
# Миллисекунды (целое число)
now_millis = int(time.time() * 1000)
print(now_millis) # Пример: 1692268800123
# Наносекунды (Python 3.7+)
now_nanos = time.time_ns()
print(now_nanos) # Пример: 1692268800123456789
# Преобразование в datetime
ts = 1692268800
dt_local = datetime.fromtimestamp(ts)
dt_utc = datetime.fromtimestamp(ts, timezone.utc)
print(dt_local.strftime("%Y-%m-%d %H:%M:%S")) # Локальное время
print(dt_utc.strftime("%Y-%m-%d %H:%M:%S")) # Время UTC
Go
Стандартная библиотека time в Go даёт несколько уровней точности:
package main
import (
"fmt"
"time"
)
func main() {
// Получить текущий Unix timestamp
sec := time.Now().Unix() // Секунды
msec := time.Now().UnixMilli() // Миллисекунды (Go 1.17+)
nsec := time.Now().UnixNano() // Наносекунды
fmt.Println(sec) // Пример: 1692268800
fmt.Println(msec) // Пример: 1692268800123
fmt.Println(nsec) // Пример: 1692268800123456789
// Преобразовать timestamp в Time
t := time.Unix(sec, 0)
fmt.Println(t.UTC())
fmt.Println(t)
}
Типичные ошибки и лучшие практики
Ошибка: непонятные единицы
// ✗ Неправильно: единицы timestamp неясны
const timestamp = 1692268800;
const date = new Date(timestamp); // Ошибка: трактуется как миллисекунды, получится 1970 год
// ✓ Правильно: явно указывать единицы
const timestampSec = 1692268800;
const timestampMs = 1692268800000;
const dateFromSec = new Date(timestampSec * 1000);
Лучшая практика именования полей
log_entry = {
"timestamp_ms": 1692268800123, # В миллисекундах
"timestamp_iso": "2023-08-17T16:00:00Z", # ISO 8601 UTC
"event_type": "user_login",
"user_id": 12345
}
Подводные камни работы с часовыми поясами
При работе с часовыми поясами есть четыре основные ловушки:
- Путаница локального времени и UTC — Unix timestamp всегда привязан к UTC; конвертируйте в локальное время только при отображении
- Не сохранять информацию о часовом поясе — это создаёт неоднозначность; всегда храните UTC или включайте смещение
- Несогласованность часовых поясов между системами — все системы должны использовать одну систему отсчёта (рекомендуется UTC)
- Ручной расчёт смещений DST — полагайтесь на встроенные библиотеки, не зашивайте смещения в код
Рекомендуемый подход: «стандартизированное хранение, локализованное отображение». На этапах хранения и передачи используйте UTC или Unix timestamp для единообразия; форматируйте под часовой пояс пользователя при отображении.
Проблемы перехода на летнее время (DST)
DST создаёт два проблемных периода:
- Пропущенное время: при переходе на летнее время часы прыгают вперёд. Например, 02:00 сразу превращается в 03:00 — момента 02:30 не существует.
- Повторяющееся время: при возврате с летнего времени промежуток 01:00–01:59 встречается дважды, что создаёт неоднозначность.
Сами Unix timestamp непрерывны и не зависят от DST, но конвертация в локальное время требует аккуратности.
Лучшие практики для логов, баз данных и API
Системы логирования
Унифицируйте часовой пояс UTC и формат ISO 8601; добавляйте миллисекунды или микросекунды, когда это необходимо.
Базы данных
Предпочитайте нативные календарные типы с поддержкой часового пояса; для числовых timestamp используйте BIGINT и явно указывайте единицы в имени поля (например, *_epoch_ms).
API
Чётко указывайте формат и единицы. Внешние интерфейсы должны использовать ISO 8601 (читаемо, включает часовой пояс); во внутренних системах допустимы числовые timestamp при условии задокументированных единиц.
Типичные сценарии ошибок
- Сбой разбора 13 цифр: миллисекундный timestamp подаётся в функцию, ожидающую секунды, и получается переполнение. Сначала определяйте единицы по числу цифр.
- Несоответствие формата: некорректные даты, отсутствие часового пояса или попадание в момент перехода на DST вызывают ошибки разбора.
- Смещения часовых поясов: целочасовые отклонения (±8 часов) обычно говорят о проблемах унификации. Внутри системы используйте UTC.
- Числовое переполнение: 32-битные системы упираются в границу 2038 года; приоритезируйте 64-битные целые.
Часто задаваемые вопросы
Почему именно 1 января 1970 года?
Разработка операционной системы Unix началась в 1970 году, к тому же это круглый год десятилетия — легко запомнить и считать. 32-битные целые могли представить даты с 1970 по 2038 год, чего на тот момент было достаточно.
Как отличить секунды от миллисекунд?
Три метода: посчитать цифры (10 цифр — секунды, 13 — миллисекунды, 16 — микросекунды, 19 — наносекунды); разобрать значение и проверить, выглядит ли получившаяся дата правдоподобно; либо воспользоваться онлайн-конвертером.
Актуальна ли проблема 2038 года?
Современные системы на 64-битных целых её в основном решили. Все основные языки программирования уже поддерживают 64-битные timestamp. Внимания требуют лишь устаревшие 32-битные системы и встраиваемые устройства.
Почему DST вызывает проблемы?
Разрыв во времени из-за пропущенного часа и повторение времени из-за повторного часа создают неоднозначность при разборе. Разные системы решают неоднозначные моменты разными стратегиями. Решение: внутри системы использовать UTC, конвертировать в локальное время только при отображении.
Почему timestamp в JavaScript и Python отличаются?
Date.now() в JavaScript возвращает миллисекунды (13 цифр), а time.time() в Python — секунды (с плавающей точкой и микросекундной точностью). Для перевода делите или умножайте на 1000.
Современные тенденции и перспективы
- Более высокая точность: финансовый трейдинг, IoT и системы реального времени требуют точности уровня наносекунд
- Распределённая синхронизация: протоколы NTP и PTP повышают точность
- Timestamp в блокчейне: криптовалюты требуют timestamp с защитой от подделки и высокой точностью
- Оптимизация производительности: SIMD-инструкции, кеширование в памяти и параллельная обработка ускоряют конвертацию
Попробуйте сами
Конвертируйте Unix timestamp мгновенно с помощью нашего конвертера Unix timestamp — автоопределение секунд, миллисекунд и микросекунд. 100 % в браузере.
Работаете с PostgreSQL? Подробный материал о ловушках часовых поясов в колонках типа timestamp разобран в руководстве по timestamp в PostgreSQL.
Итог
В этом руководстве разобраны основы Unix timestamp — от происхождения эпохи и многоточностной конвертации до реализаций в разных языках, работы с часовыми поясами, нюансов DST и инженерных практик в логах, базах данных и API. Главный вывод: храните в UTC, отображайте в локальном времени и всегда явно указывайте единицы timestamp.
Timestamp — лишь часть инструментария разработчика. Подборка остальных полезных инструментов для кодирования, хеширования и преобразования данных разобрана в подборке базовых инструментов разработчика.