Работа с timestamp

Timestamp (временная метка) в JavaScript представляет собой числовое значение, отражающее количество времени, прошедшего с 1 января 1970 года 00:00:00 UTC (Unix Epoch). В большинстве современных систем используется формат в миллисекундах, тогда как классический Unix timestamp — в секундах.

В экосистеме JavaScript различие между этими двумя форматами является источником частых ошибок, поэтому работа с ними в date-fns требует строгого понимания преобразований.


Базовые представления timestamp

В JavaScript стандартный timestamp в миллисекундах получается через:

Date.now()

или:

new Date().getTime()

Оба выражения возвращают одно и то же значение — количество миллисекунд.

Пример:

const ts = Date.now();
console.log(ts); // 1737550000000

Unix timestamp в секундах:

Math.floor(Date.now() / 1000);

Разница между форматами критична при взаимодействии с API, базами данных и сторонними сервисами.


Получение timestamp через date-fns

В date-fns предусмотрен набор функций для работы с временными метками без необходимости ручных вычислений.

getUnixTime

Функция getUnixTime возвращает timestamp в секундах:

import { getUnixTime } from 'date-fns';

const now = new Date();
const ts = getUnixTime(now);

console.log(ts); // 1737550000

Особенность: результат всегда нормализован к секундам, что удобно для API, использующих Unix формат.


getTime

Функция getTime возвращает timestamp в миллисекундах:

import { getTime } from 'date-fns';

const now = new Date();
const ts = getTime(now);

console.log(ts); // 1737550000000

Функционально эквивалентна Date.prototype.getTime, но используется для унификации кода при работе через date-fns.


Преобразование timestamp в Date

fromUnixTime

Для преобразования секундного timestamp в объект Date используется fromUnixTime:

import { fromUnixTime } from 'date-fns';

const ts = 1737550000;
const date = fromUnixTime(ts);

console.log(date);

Важно учитывать, что входное значение строго в секундах. Передача миллисекунд приведёт к некорректной дате.


Преобразование миллисекунд вручную

date-fns не требует отдельной функции для миллисекундного timestamp, так как стандартный конструктор Date уже работает с этим форматом:

const ts = 1737550000000;
const date = new Date(ts);

Унификация timestamp форматов

В реальных приложениях часто требуется нормализация входящих данных. API могут возвращать:

  • секунды (Unix timestamp)
  • миллисекунды
  • строки с числом
  • ISO-строки

date-fns не скрывает различий форматов, но предоставляет инструменты для безопасной работы.

Пример нормализации:

import { fromUnixTime, isValid } from 'date-fns';

function normalizeTimestamp(value) {
  if (typeof value === 'string') {
    value = Number(value);
  }

  if (value < 1e12) {
    return fromUnixTime(value);
  }

  return new Date(value);
}

Логика основана на эвристике: значения меньше 1e12 почти всегда являются секундами.


Получение timestamp из Date

Секунды

import { getUnixTime } from 'date-fns';

const date = new Date('2025-01-01T00:00:00Z');
const ts = getUnixTime(date);

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

import { getTime } from 'date-fns';

const date = new Date('2025-01-01T00:00:00Z');
const ts = getTime(date);

Разделение этих функций устраняет неоднозначность, которая часто возникает при использовании чистого JavaScript.


Арифметика timestamp

timestamp удобно использовать для вычислений времени. В date-fns операции выполняются через специализированные функции.


differenceInMilliseconds

import { differenceInMilliseconds } from 'date-fns';

const a = new Date('2025-01-01');
const b = new Date('2025-01-02');

const diff = differenceInMilliseconds(b, a);

Результат:

86400000

differenceInSeconds

import { differenceInSeconds } from 'date-fns';

const diff = differenceInSeconds(b, a);

Практическое использование timestamp разницы

import { getUnixTime } from 'date-fns';

function isExpired(createdAt, ttlSeconds) {
  const now = getUnixTime(new Date());
  return now - createdAt > ttlSeconds;
}

Модификация timestamp через операции времени

Хотя timestamp — числовая величина, date-fns оперирует объектами Date, обеспечивая более безопасные операции.


addMilliseconds

import { addMilliseconds } from 'date-fns';

const now = new Date();
const later = addMilliseconds(now, 5000);

addSeconds и связка с timestamp

import { addSeconds, getUnixTime } from 'date-fns';

const now = new Date();
const future = addSeconds(now, 30);

const ts = getUnixTime(future);

Конвертация timestamp для API

При работе с REST или GraphQL часто требуется строгое соответствие форматов.

Пример отправки Unix timestamp

import { getUnixTime } from 'date-fns';

const payload = {
  createdAt: getUnixTime(new Date()),
};

Пример обработки ответа API

import { fromUnixTime } from 'date-fns';

function parseResponse(data) {
  return {
    ...data,
    createdAt: fromUnixTime(data.createdAt),
  };
}

Работа с числовыми строками timestamp

Часто timestamp приходит как строка:

const raw = "1737550000";

Приведение:

import { fromUnixTime } from 'date-fns';

const date = fromUnixTime(Number(raw));

Без явного преобразования возникает риск неявных ошибок при типизации и сериализации.


Проверка валидности timestamp

date-fns предоставляет универсальную проверку дат:

import { isValid } from 'date-fns';

const date = new Date(1737550000000);

console.log(isValid(date));

Эта проверка особенно важна при обработке внешних данных.


Сравнение timestamp вместо Date

В некоторых сценариях выгоднее работать с числовыми значениями:

import { getTime } from 'date-fns';

const a = getTime(new Date('2025-01-01'));
const b = getTime(new Date('2025-01-10'));

if (b > a) {
  // более поздняя дата
}

Числовое сравнение быстрее и исключает необходимость вызовов методов Date.


Частые ошибки при работе с timestamp

Перепутанные секунды и миллисекунды

fromUnixTime(Date.now()) // ошибка: Date.now() в миллисекундах

Корректный вариант:

fromUnixTime(Math.floor(Date.now() / 1000))

Неявное преобразование строк

fromUnixTime("1737550000") // работает, но рискованно

Рекомендуемое явное приведение:

fromUnixTime(Number("1737550000"))

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

При делении миллисекунд на 1000 возможна потеря дробной части, что критично в системах с высокой точностью событий.


Timestamp в высоконагруженных системах

В системах логирования и аналитики timestamp используется как основной идентификатор события. date-fns применяется для:

  • нормализации входящих событий
  • приведения времени к единому формату
  • агрегации по временным интервалам

Пример агрегации:

import { getUnixTime } from 'date-fns';

function bucketEvent(date) {
  const ts = getUnixTime(date);
  return Math.floor(ts / 60) * 60;
}

Здесь события группируются по минутам.


Преобразование timestamp для UI

Часто timestamp требуется преобразовать в читаемую дату:

import { fromUnixTime, format } from 'date-fns';

const date = fromUnixTime(1737550000);

const view = format(date, 'yyyy-MM-dd HH:mm:ss');

timestamp выступает промежуточным слоем между сервером и представлением.


Синхронизация timestamp в распределённых системах

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

const ts = getUnixTime(new Date(Date.now()));

Все вычисления выполняются относительно UTC, чтобы исключить локальные смещения времени системы.


Интеграция timestamp с кешированием

timestamp часто используется как ключ обновления кеша:

import { getUnixTime } from 'date-fns';

function cacheKey(prefix) {
  return `${prefix}:${getUnixTime(new Date())}`;
}

Обработка временных меток в потоках данных

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

import { getTime } from 'date-fns';

const events = [
  { t: getTime(new Date('2025-01-01')) },
  { t: getTime(new Date('2024-01-01')) },
];

events.sort((a, b) => a.t - b.t);