«Unix Timestamp против ISO 8601: что выбрать?»

Разработчик сравнивает форматы Unix timestamp и ISO 8601 для API и баз данных

Если ты хоть раз интегрировал две системы с разными форматами хранения дат, ты знаешь, как это больно. Один API возвращает 1714521600, другой — 2024-05-01T00:00:00Z, и вот ты уже пишешь логику конвертации в полночь. Правильный выбор между форматом Unix timestamp и ISO 8601 с самого начала экономит часы отладки и предотвращает трудноуловимые баги в продакшене. Оба формата широко используются, у каждого есть реальные преимущества, и ни один не является универсально «лучшим». Главное — чётко понимать, когда каждый из них подходит и почему неверный выбор создаёт реальные проблемы.

Главное:

  • Unix timestamp — это целое число, отсчитывающее секунды (или миллисекунды) с 1 января 1970 года UTC. Идеален для вычислений, хранения и работы с API.
  • ISO 8601 — стандартизированный строковый формат, понятный человеку. Идеален для логов, пользовательских интерфейсов и межсистемного обмена данными.
  • Эти два формата дополняют друг друга, а не конкурируют. Многие продакшен-системы хранят Unix time внутри, а наружу отдают ISO 8601.
  • Неверный выбор формата порождает баги с часовыми поясами, ошибки парсинга и излишнюю сложность.

Что такое формат Unix timestamp?

Unix timestamp (также известный как Unix time или epoch time) — это одно целое число, представляющее количество секунд, прошедших с момента Unix epoch: 1 января 1970 года, 00:00:00 UTC. Формат Unix time не зависит от часового пояса по определению, поскольку всегда привязан к UTC. Никакой неоднозначности из-за летнего времени или региональных смещений.

Например, Unix timestamp 1714521600 обозначает ровно один конкретный момент времени — независимо от того, в какой точке мира ты его читаешь. Современные системы нередко расширяют точность до миллисекунд (1714521600000) или микросекунд. Подробнее об этих вариациях — в нашем руководстве по секундам, миллисекундам и микросекундам в Unix timestamps.

Технически Unix timestamp — просто число. Эта простота одновременно является его главным достоинством и источником главной проблемы с читаемостью.

Подробнее о происхождении этой концепции читай в нашей статье об epoch time и его основах.

Что такое формат даты ISO 8601?

ISO 8601 — международный стандарт, опубликованный Международной организацией по стандартизации, который определяет, как представлять даты и время в виде строк. Типичная дата и время в формате ISO 8601 выглядят так: 2024-05-01T00:00:00Z.

Разберём по частям:

  • 2024-05-01 — дата в формате YYYY-MM-DD
  • T — разделитель между датой и временем
  • 00:00:00 — время в формате HH:MM:SS
  • Z — обозначает UTC (можно также использовать смещения вида +05:30)

ISO 8601 лежит в основе стандарта RFC 3339, широко применяемого в интернет-протоколах. Он понятен человеку, сортируется как строка и однозначен в любой локали. В отличие от записи «05/01/2024», которая означает 1 мая в США и 5 января в Европе, ISO 8601 одинаково интерпретируется по всему миру.

Ключевые отличия на первый взгляд

Свойство Формат Unix timestamp Формат даты ISO 8601
Тип данных Целое число (или float) Строка
Читаемость человеком Нет Да
Обработка часовых поясов Всегда UTC (неявно) Явное смещение или Z
Удобство для вычислений Да (вычитание, сравнение) Нет (требует парсинга)
Размер при хранении Малый (4–8 байт) Больше (20+ символов)
Сортировка без преобразования Да (числовая сортировка) Да (лексикографическая)
Независимость от локали Да Да

Когда использовать формат Unix timestamp

Формат Unix time отлично проявляет себя в конкретных, чётко определённых ситуациях. Используй его, когда:

1. Нужно выполнять арифметику с датами

Вычисление длительностей с Unix timestamps тривиально: чтобы узнать, сколько секунд прошло, достаточно вычесть одно целое число из другого. С ISO 8601 строками сначала нужно распарсить оба значения в объекты datetime, а затем вычислить разницу. При высокочастотных операциях (например, логирование миллионов событий) накладные расходы на парсинг ощутимо накапливаются.

2. Хранение дат в базах данных

Целочисленные колонки индексируются и сравниваются быстрее строковых. Если ты выполняешь запросы вида «дай все события за последние 7 дней», сравнение двух целых чисел эффективнее, чем парсинг и сравнение строк. Наше подробное руководство по Unix timestamps в базах данных подробно рассматривает стратегии индексирования и паттерны запросов.

3. Взаимодействие между внутренними сервисами

Когда двум бэкенд-сервисам под твоим контролем нужно передавать временны́е метки, формат Unix снижает сложность парсинга. Обе стороны договариваются о целочисленном контракте, и нет риска неверной интерпретации строки с часовым поясом.

4. Логика истечения срока действия и TTL

JWT-токены, записи кэша и сессии почти повсеместно используют Unix timestamps для задания срока действия. Поле exp в JSON Web Token (JWT) — именно Unix timestamp: сравнение exp > Date.now() / 1000 — это одна быстрая целочисленная операция.

5. Устранение багов с часовыми поясами

Поскольку Unix timestamps всегда UTC, они полностью исключают целый класс багов, связанных с переходом на летнее время. Если твоё приложение обслуживает пользователей в разных часовых поясах, хранить Unix timestamps и конвертировать их в локальное время только на уровне отображения — проверенный архитектурный паттерн.

Обрати внимание на проблему 2038 года, если ты используешь 32-битные знаковые целые для хранения Unix timestamps — в современных системах всегда применяй 64-битные целые числа.

Когда использовать формат даты ISO 8601

Формат даты ISO 8601 выигрывает там, где людям или внешним системам нужно читать, писать или валидировать даты без запуска кода.

1. Ответы API для сторонних разработчиков

Если ты строишь публичный API, вернуть "created_at": "2024-05-01T12:30:00Z" гораздо удобнее для разработчика, чем "created_at": 1714562200. Внешний разработчик сразу понимает значение, не конвертируя его. Многие руководства по стилю API — в том числе от Stripe и GitHub — по умолчанию используют ISO 8601 именно по этой причине.

2. Лог-файлы и журналы аудита

Логи читают люди во время инцидентов. Строка лога [2024-05-01T14:22:05Z] ERROR: payment failed сразу даёт нужную информацию. Строка [1714569725] ERROR: payment failed заставляет сначала конвертировать временну́ю метку, прежде чем приступить к отладке.

3. Интернационализация и локализация

ISO 8601 включает явную информацию о смещении часового пояса. Когда системе нужно сохранить исходное местное время пользователя (например, событие в календаре, созданное в 9:00 утра в Токио), ISO 8601 с правильным смещением (2024-05-01T09:00:00+09:00) сохраняет этот контекст. Unix timestamp сам по себе не может сообщить, в каком часовом поясе находился пользователь при создании события.

4. Конфигурационные файлы и форматы обмена данными

JSON, YAML и CSV-файлы, которые редактируют люди, должны использовать ISO 8601. Если разработчику нужно вручную задать дату истечения срока в конфиге, написать 2025-01-01T00:00:00Z гораздо менее чревато ошибкой, чем вычислять и вписывать Unix timestamp руками.

Примеры кода на JavaScript и Python

JavaScript: конвертация между форматами

// Получить текущий Unix timestamp (в секундах)
const unixNow = Math.floor(Date.now() / 1000);
console.log(unixNow); // например, 1714521600

// Конвертировать Unix timestamp в строку ISO 8601
const isoString = new Date(unixNow * 1000).toISOString();
console.log(isoString); // "2024-05-01T00:00:00.000Z"

// Конвертировать строку ISO 8601 обратно в Unix timestamp
const parsed = new Date("2024-05-01T00:00:00Z");
const backToUnix = Math.floor(parsed.getTime() / 1000);
console.log(backToUnix); // 1714521600

// Вычислить длительность между двумя Unix timestamps (парсинг не нужен)
const start = 1714521600;
const end = 1714608000;
const durationSeconds = end - start;
console.log(`Duration: ${durationSeconds / 3600} hours`); // 24 hours

Python: работа с обоими форматами

import time
from datetime import datetime, timezone

# Получить текущий Unix timestamp
unix_now = int(time.time())
print(unix_now)  # например, 1714521600

# Конвертировать Unix timestamp в строку ISO 8601
dt = datetime.fromtimestamp(unix_now, tz=timezone.utc)
iso_string = dt.isoformat()
print(iso_string)  # "2024-05-01T00:00:00+00:00"

# Конвертировать строку ISO 8601 обратно в Unix timestamp
parsed_dt = datetime.fromisoformat("2024-05-01T00:00:00+00:00")
back_to_unix = int(parsed_dt.timestamp())
print(back_to_unix)  # 1714521600

# Вычислить длительность — с Unix timestamps это тривиально
start = 1714521600
end = 1714608000
duration_hours = (end - start) / 3600
print(f"Duration: {duration_hours} hours")  # 24.0 hours

Важно: В Python всегда передавай tz=timezone.utc при вызове datetime.fromtimestamp(). Без этого Python использует локальный часовой пояс системы, что может давать некорректные результаты на серверах в других регионах.

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

Представь, что ты строишь API для бронирования отелей. Пользователь из Нью-Йорка бронирует номер с заездом 15 июня 2024 года в 15:00 по местному времени. Вот как два формата ведут себя на практике.

Хранение как Unix timestamp: ты конвертируешь местное время пользователя в UTC и сохраняешь 1718470800. Это компактно и быстро для запросов. Но когда сотрудник отеля в Нью-Йорке смотрит на сырую запись в базе, он видит просто число. Нужен инструмент для декодирования. Хуже того: если забыть сконвертировать местное время в UTC перед сохранением, в систему закрадётся незаметный баг на 4 часа (Нью-Йорк летом — UTC-4).

Хранение как ISO 8601: ты сохраняешь 2024-06-15T15:00:00-04:00. Смещение сохранено. Сотрудник может прочитать запись напрямую. Исходный контекст часового пояса не теряется. Но строковые сравнения в SQL чуть медленнее, а вычисление «сколько часов до заезда» требует предварительного парсинга строки.

Решение, которое применяет большинство команд в продакшене: хранить Unix timestamp в базе данных ради производительности и корректности, а в ответе API возвращать строку ISO 8601 ради удобства. Именно этот паттерн используют крупные платформы. Получаешь лучшее от обоих миров.

Полное руководство по паттернам конвертации смотри в нашем полном руководстве по конвертации Unix timestamp в дату.

Чёткие рекомендации по сценариям использования

Основываясь на реальных ограничениях, вот прямые рекомендации для каждого сценария:

  • Хранение в базе данных: используй Unix timestamp (целое число). Быстрее индексируется, не требует парсинга часового пояса, занимает меньше места.
  • Взаимодействие внутренних микросервисов: используй Unix timestamp. Обе стороны контролируют контракт, и никто не читает сырой payload.
  • Ответы публичного REST API: используй ISO 8601. Сторонним разработчикам нужны читаемые, самодокументируемые значения.
  • Лог-файлы и журналы аудита: используй ISO 8601. Люди читают логи в стрессовых ситуациях во время инцидентов.
  • JWT и истечение срока сессии: используй Unix timestamp. Спецификация требует именно этого, а сравнение — одна операция.
  • Конфигурационные файлы и запланированные задачи: используй ISO 8601. Люди пишут и редактируют эти файлы напрямую.
  • Функции календаря и планирования: используй ISO 8601 с явным смещением часового пояса. Сохраняет исходный контекст часового пояса пользователя.
  • Арифметика с датами в логике приложения: сначала конвертируй в Unix timestamp, выполни вычисления, затем при необходимости конвертируй обратно.

Более широкий набор лучших практик работы с временны́ми метками в бэкенд-коде — в нашем руководстве по Unix timestamp для разработчиков, где подробно рассмотрены паттерны хранения, форматирования и работы с часовыми поясами.

Заключение

Спор между форматом Unix timestamp и форматом даты ISO 8601 — не о том, какой из них лучше. Речь идёт о том, чтобы подобрать правильный инструмент для конкретной задачи. Unix timestamps — для колонок в базе данных, внутренних контрактов между сервисами и логики истечения срока действия. ISO 8601 — для ответов API, логов и любых файлов, которые может открыть человек. Большинство надёжных продакшен-систем используют оба формата: хранят как Unix time, отдают наружу как ISO 8601. Если ты усвоишь этот единственный паттерн, ты предотвратишь самые распространённые баги с датами ещё до того, как они доберутся до продакшена.

Бесплатный конвертер Unix timestamp — мгновенная конвертация между Unix time и ISO 8601

Перестань гадать, какой формат даты использовать

Попробуй наш бесплатный конвертер Unix timestamp на unixtimestamp.app и мгновенно конвертируй между Unix time и ISO 8601 — без единой строки кода. Вставь временну́ю метку — получи читаемую дату за секунды.

Попробовать бесплатно →

Да, и многие базы данных поддерживают нативные типы datetime, которые хранят ISO 8601 внутри. Однако целочисленные Unix timestamps, как правило, быстрее при диапазонных запросах и сравнениях по индексу. Для высоконагруженных таблиц с частой фильтрацией по датам целочисленные временны́е метки дают ощутимое преимущество в производительности по сравнению со строковыми или datetime-колонками.

Unix timestamps по определению всегда UTC. Они не хранят информацию о часовом поясе. Чтобы отобразить Unix timestamp в локальном часовом поясе пользователя, конвертация выполняется на уровне представления. На самом деле это преимущество: сохранённое значение абсолютно однозначно, а конвертация часового пояса выполняется явно там, где ей и место.

Unix timestamps в секундах (например, 1714521600) — традиционный формат, используемый в большинстве Unix-систем и стандартов вроде JWT. Миллисекунды (например, 1714521600000) распространены в JavaScript и браузерных окружениях. Всегда уточняй, какую точность ожидает API: если отправить секунды туда, где ждут миллисекунды, получишь даты, отстающие в 1000 раз.

RFC 3339 — это профиль ISO 8601, разработанный специально для использования в интернете. Он немного строже: требует обязательного смещения часового пояса (например, Z или +00:00) и запрещает некоторые опциональные возможности ISO 8601. На практике большинство разработчиков считают их взаимозаменяемыми для стандартных строк вида 2024-05-01T00:00:00Z.

GitHub использует строки ISO 8601 в ответах своего REST API. Stripe использует Unix timestamps (целые числа) в своём API. Оба выбора осознанны и соответствуют их сценариям использования. Это наглядно показывает: единого отраслевого правила нет — правильный выбор зависит от аудитории твоего API и операций, которые потребители должны выполнять с этими значениями.