Unix-временные метки Как конвертировать и почему они повсюду

Опубликовано

Практическое руководство по работе с Unix-временными метками: секунды против миллисекунд, преобразование на JavaScript, Python, SQL и bash, ловушки с часовым поясом, избегаемые, и когда использовать временные метки вместо строк в формате ISO 8601.

Unix-временные метки: как конвертировать и почему они повсеместны 1
Реклама · УДАЛИТЬ?
Unix-моменты: как конвертировать и почему они повсюду

Unix-временная метка — это количество секунд, прошедших с 1 января 1970 года в 00:00:00 UTC — также называемое Unix-эпохой. Эта дата была выбрана не по техническим причинам, а потому что она была текущим годом, когда разрабатывался Unix. Эпоха всегда указывается в UTC, что означает, что временная метка, например, 1712800000 означает один и тот же момент во всех частях планеты, независимо от часового пояса.

Unix-временные метки используются повсеместно: в HTTP-заголовках, JWT-токенах, записях в базах данных, лог-файлах, очередях сообщений и ответах API. Если вы разрабатываете или отлаживаете что-либо, связанное со временем, вы столкнетесь с ними постоянно. Конвертер Unix-временных меток IO Tools полезен для быстрых поисков, но вам также нужно знать, как обрабатывать их в коде.

Секунды против миллисекунд: ошибка, которая затрудняет всех

Наиболее распространённая ошибка с временной меткой в производственной среде: путаница между секундами и миллисекундами. Стандарт Unix использует секунды. В JavaScript функция Date.now() возвращает миллисекунды. Так же и Java System.currentTimeMillis().

Временная метка 1712800000 соответствует апрелю 2024 года. Временная метка 1712800000000 (миллисекунды) относится к году 56 000-го. Если ваши расчёты даты приводят к датам, которые на десятилетия в будущем, или если отображаются даты, которые находятся в будущем, это почти всегда причина. 1970-01-01Правило: если временная метка имеет 13 цифр, это миллисекунды. Если 10 цифр — это секунды. Если не уверены, поделите на 1000 и проверьте, имеет ли результат смысл.

Правило: если временная метка имеет 13 цифр, это миллисекунды, 10 цифр — это секунды. Если неясно, поделите на 1000 и проверьте, имеет ли результат смысл.

Конвертация Unix-временных меток по языкам

Вот паттерны, которые вы будете использовать на практике:

JavaScript

// Get current timestamp (milliseconds — divide by 1000 for seconds)
const tsMs = Date.now();           // e.g. 1712800000000
const tsSec = Math.floor(Date.now() / 1000); // e.g. 1712800000

// Convert seconds timestamp to Date object
const ts = 1712800000;
const date = new Date(ts * 1000);  // must multiply by 1000
console.log(date.toISOString());   // "2024-04-11T02:13:20.000Z"

// Convert Date back to Unix timestamp (seconds)
const tsBack = Math.floor(date.getTime() / 1000);

Питон

from datetime import datetime, timezone

# Get current timestamp (seconds)
import time
ts = int(time.time())  # e.g. 1712800000

# Convert timestamp to datetime (UTC-aware)
dt = datetime.fromtimestamp(ts, tz=timezone.utc)
print(dt.isoformat())  # 2024-04-11T02:13:20+00:00

# Convert local-naive datetime to timestamp (risky — see timezone section)
ts_back = int(dt.timestamp())

SQL (MySQL / MariaDB)

-- Convert timestamp to datetime
SELECT FROM_UNIXTIME(1712800000);
-- Result: 2024-04-11 02:13:20 (server timezone applies here)

-- Get current Unix timestamp
SELECT UNIX_TIMESTAMP();

-- Convert datetime string to timestamp
SELECT UNIX_TIMESTAMP('2024-04-11 02:13:20');

Bash

# Get current timestamp
date +%s

# Convert timestamp to human-readable (GNU date)
date -d @1712800000
# Output: Thu Apr 11 02:13:20 UTC 2024

# macOS (BSD date)
date -r 1712800000

Таблица быстрого справки

ЯзыкПолучить текущее значение (в секундах)Временная метка → датаДата → временная метка
JavaScriptMath.floor(Date.now()/1000)new Date(ts * 1000)Math.floor(d.getTime()/1000)
Питонint(time.time())datetime.fromtimestamp(ts, tz=timezone.utc)int(dt.timestamp())
MySQLUNIX_TIMESTAMP()FROM_UNIXTIME(ts)UNIX_TIMESTAMP(datetime_str)
Bashdate +%sdate -d @tsdate -d "2024-04-11" +%s

Опасности часовых поясов

Unix-временные метки всегда в UTC. Всегда. Число 1712800000 не имеет часового пояса — оно просто считает секунды с эпохи. Часовой пояс — это вопрос отображения, а не хранения.

Где разработчики сталкиваются с проблемами:

  • Python’s datetime.fromtimestamp(ts) без tz=timezone.utc — использует локальный часовой пояс сервера, без каких-либо уведомлений. Используйте fromtimestamp(ts, tz=timezone.utc) вместо.
  • MySQL’s FROM_UNIXTIME() — преобразует в настройку часового пояса сервера MySQL (@@session.time_zone). Если ваш сервер находится в UTC+8, результат сдвигается на 8 часов.
  • Хранение datetime в MySQL без нормализации в UTC — если ваш сервер приложения и сервер базы данных находятся в разных часовых поясах, каждый ввод и извлечение данных — это ошибка, ждущая своего часа.

Паттерн, который избегает всех этих проблем: хранить Unix-временные метки в базе данных, преобразовывать в человеко-понятный формат на уровне приложения при отображении, используя предпочитаемый часовой пояс пользователя.

Временные метки против строк по ISO 8601: что хранить

Оба формата являются допустимыми для хранения. Преимущества и недостатки:

  • Unix-временная метка (целое число): компактная, быстрая при сравнении и арифметических операциях, без неопределённости по часовому поясу, работает во всех базах данных. Недостаток: нечитаема без инструмента.
  • Строка по ISO 8601 (например, 2024-04-11T02:13:20Z): человеко-понятная в базе данных, самодокументированная. Недостаток: медленнее при запросах по диапазону, часовой пояс может быть случайно опущен или указан неверно.

Для большинства приложений: храните временные метки как целые числа. Используйте ISO 8601 в API и логах, где важна человеко-понятность. Если вы обязаны хранить ISO 8601, всегда включайте Z или явный сдвиг — без часового пояса 2024-04-11 02:13:20 в таких случаях — это катастрофа в распределённых системах.

Проблема 2038 года

32-битные целые числа могут хранить максимальное значение 2147483647, что соответствует 1 января 2038 года в 03:14:07 UTC. Системы, хранящие Unix-временные метки в 32-битных int превысят это значение и переполнятся — вернётся к 1901 году или аварийно остановятся.

Нужно ли беспокоиться? Если вы пишете новый код — нет — используйте 64-битные целые числа. Если вы поддерживаете устаревший C-код, встраиваемое ПО или старые схемы MySQL, использующие INT(11) для временных меток, стоит провести аудит. Тип TIMESTAMP в MySQL также затронут; DATETIME не затронут. Современные системы, использующие 64-битные временные метки, безопасны на протяжении более чем 292 миллиардов лет.

Нужно быстро конвертировать временные метки без написания кода? Конвертер временных меток на IO Tools обрабатывает секунды и миллисекунды, показывает время UTC и локальное время рядом и позволяет вставить дату для получения временной метки. обрабатывает секунды и миллисекунды, показывает время UTC и локальное время рядом и позволяет вставить дату для получения временной метки.

Хотите убрать рекламу? Откажитесь от рекламы сегодня

Установите наши расширения

Добавьте инструменты ввода-вывода в свой любимый браузер для мгновенного доступа и более быстрого поиска

в Расширение Chrome в Расширение края в Расширение Firefox в Расширение Opera

Табло результатов прибыло!

Табло результатов — это интересный способ следить за вашими играми, все данные хранятся в вашем браузере. Скоро появятся новые функции!

Реклама · УДАЛИТЬ?
Реклама · УДАЛИТЬ?
Реклама · УДАЛИТЬ?

новости с техническими моментами

Примите участие

Помогите нам продолжать предоставлять ценные бесплатные инструменты

Купи мне кофе
Реклама · УДАЛИТЬ?