Skip to content
Назад к блогу
Руководства

Руководство по Unix timestamp: точность, часовые пояса и DST

Unix timestamp подробно: происхождение эпохи, конвертация секунд/мс/мкс, работа с часовыми поясами, ловушки летнего времени и примеры кода на JS, Python и Go.

14 мин чтения

Полное руководство по 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)110Традиционные системы Unix/Linux
Миллисекунды (ms)100013JavaScript, Java, логирование
Микросекунды (μs)1 000 00016Распределённый трейсинг, базы данных
Наносекунды (ns)1 000 000 00019Язык 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
}

Подводные камни работы с часовыми поясами

При работе с часовыми поясами есть четыре основные ловушки:

  1. Путаница локального времени и UTC — Unix timestamp всегда привязан к UTC; конвертируйте в локальное время только при отображении
  2. Не сохранять информацию о часовом поясе — это создаёт неоднозначность; всегда храните UTC или включайте смещение
  3. Несогласованность часовых поясов между системами — все системы должны использовать одну систему отсчёта (рекомендуется UTC)
  4. Ручной расчёт смещений 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 — лишь часть инструментария разработчика. Подборка остальных полезных инструментов для кодирования, хеширования и преобразования данных разобрана в подборке базовых инструментов разработчика.

Похожие статьи

Все статьи