Получение Unix-времени

Unix-время представляет собой способ измерения времени как количества секунд, прошедших с 1 января 1970 года 00:00:00 UTC (эпоха Unix). В JavaScript и библиотеке Moment.js работа с этим форматом сводится к двум основным вариантам: получение значения в секундах и получение значения в миллисекундах. Различие между ними критически важно, так как большинство ошибок при работе с временными метками связано именно с несоответствием единиц измерения.

Moment.js хранит внутреннее представление времени с точностью до миллисекунд. Это означает, что любые операции преобразования должны учитывать, что базовая единица в JavaScript — миллисекунда, тогда как Unix-время в классическом виде чаще выражается в секундах.


Каждый объект Moment содержит дату и время с точностью до миллисекунд. Это делает его совместимым с Date, но добавляет удобные методы для преобразования в Unix-форматы.

Внутренне Moment использует timestamp, аналогичный Date.getTime(), то есть количество миллисекунд с эпохи Unix:

const m = moment();
console.log(m.valueOf()); // миллисекунды
console.log(+m);          // то же самое, неявное приведение

Метод valueOf() является ключевым, так как он возвращает числовое представление момента времени, пригодное для арифметики и хранения.


Получение текущего Unix-времени в секундах

Для получения Unix-времени в секундах используется метод unix():

const now = moment().unix();
console.log(now);

Результат — целое число, выражающее количество секунд с начала эпохи Unix.

Особенность метода заключается в том, что он автоматически округляет значение вниз (floor), отбрасывая миллисекунды. Это важно учитывать при сравнении временных меток.


Различие между seconds и milliseconds

На практике встречаются два формата:

  • Unix time в секундах: 1710000000
  • Unix time в миллисекундах: 1710000000000

Moment.js предоставляет оба варианта через разные методы:

const m = moment();

const seconds = m.unix();
const milliseconds = m.valueOf();

Основное правило:

  • unix() → секунды
  • valueOf() → миллисекунды

Ошибка возникает, когда одно значение интерпретируется как другое, например, при передаче секунд в Date или Moment без умножения на 1000.


Создание Moment из Unix-времени

Moment позволяет создавать объект времени напрямую из Unix-метки.

Из секунд

const m = moment.unix(1710000000);
console.log(m.format());

Метод moment.unix() ожидает именно секунды, а не миллисекунды.

Из миллисекунд

Если имеется значение в миллисекундах, используется стандартный конструктор:

const m = moment(1710000000000);
console.log(m.format());

В этом случае Moment интерпретирует число как миллисекунды.


Типичная ошибка с единицами измерения

Наиболее распространённая проблема — передача Unix-времени в секундах туда, где ожидаются миллисекунды:

const wrong = moment(1710000000); // интерпретируется как миллисекунды

Результат будет некорректным, так как дата окажется в 1970 году.

Правильный вариант:

const correct = moment.unix(1710000000);

Преобразование Moment в Unix-время

Moment позволяет легко конвертировать объект обратно в Unix-формат.

Секунды

const m = moment();
const unixSeconds = m.unix();

Миллисекунды

const m = moment();
const unixMs = m.valueOf();

Эти операции часто используются при сохранении времени в базе данных или передаче через API.


Взаимосвязь с Date.now()

В JavaScript существует нативный способ получения времени:

Date.now()

Он возвращает миллисекунды с эпохи Unix, что эквивалентно:

moment().valueOf()

Сравнение:

console.log(Date.now());
console.log(moment().valueOf());

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


Округление и потеря точности

Метод unix() всегда отбрасывает миллисекунды:

const m = moment('2026-01-01T00:00:00.999Z');

console.log(m.unix()); // секунды без дробной части

Это поведение может приводить к потере точности при расчётах интервалов менее одной секунды.

Если требуется сохранить точность, используется valueOf():

const precise = m.valueOf();

Использование Unix-времени в арифметике

Unix-метки удобны для вычисления разницы между моментами времени:

const start = moment().unix();

setTimeout(() => {
  const end = moment().unix();
  console.log(end - start);
}, 2000);

Результат будет приблизительно равен 2 секундам.

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

const start = moment().valueOf();

setTimeout(() => {
  const end = moment().valueOf();
  console.log(end - start);
}, 2000);

Конвертация между форматами

Иногда требуется преобразование секунд в миллисекунды и обратно без Moment:

const seconds = 1710000000;
const ms = seconds * 1000;

const backToSeconds = Math.floor(ms / 1000);

Moment.js предоставляет более читаемую альтернативу:

const m = moment.unix(seconds);
const again = m.unix();

Влияние временной зоны

Unix-время всегда основано на UTC и не зависит от локальной временной зоны. Moment.js также учитывает это при работе с unix() и valueOf().

const m = moment.unix(1710000000);

console.log(m.utc().format());
console.log(m.local().format());

Несмотря на различие отображения, Unix-значение остаётся неизменным.


Преобразование строковых временных меток

При работе с API часто приходят строки, содержащие Unix-время:

const input = "1710000000";
const m = moment.unix(Number(input));

Без явного приведения к числу возможны ошибки интерпретации.


Проверка корректности Unix-значений

Moment предоставляет инструменты для валидации:

const m = moment.unix(1710000000);

console.log(m.isValid());

Некорректные значения, например NaN, приведут к false.


Сравнение Unix-времени между моментами

Moment поддерживает прямое сравнение через числовые значения:

const a = moment().unix();
const b = moment().add(1, 'day').unix();

console.log(a < b);

Такой подход предпочтителен для сортировки и фильтрации временных рядов.


Использование в API и базах данных

Unix-время часто используется как универсальный формат передачи:

const payload = {
  createdAt: moment().unix()
};

При восстановлении данных:

const m = moment.unix(payload.createdAt);

Этот подход обеспечивает независимость от форматов даты и локализации.


Особенности хранения больших значений

В некоторых системах Unix-время в миллисекундах может превышать безопасный диапазон 32-битных чисел. Moment.js использует 64-битное представление, что позволяет безопасно работать с современными датами:

const big = moment().valueOf();

Связь Unix-времени и форматирования

Unix-значение используется как промежуточный слой между вычислениями и форматированием:

const m = moment.unix(moment().unix());

console.log(m.format('YYYY-MM-DD HH:mm:ss'));

Такой подход часто применяется при сериализации и десериализации временных данных в приложениях.