formatDistanceToNow и formatDistanceToNowStrict

Функция formatDistanceToNow в библиотеке Date-fns используется для вычисления и форматирования временной разницы между заданной датой и текущим моментом. Результат выражается в человекочитаемом виде: «5 минут назад», «около 2 месяцев», «через 3 дня» — в зависимости от направления времени и настроек.

Базовая сигнатура

formatDistanceToNow(date, options)
  • date — объект Date или timestamp
  • options — объект конфигурации (необязательный)

Основной принцип работы

Функция вычисляет разницу между текущим временем и переданной датой, после чего преобразует её в наиболее подходящую единицу времени (секунды, минуты, часы, дни, месяцы, годы).

Пример:

import { formatDistanceToNow } from 'date-fns';

const date = new Date(2025, 0, 1);

console.log(formatDistanceToNow(date));

Возможный результат:

"about 1 year ago"

Если дата находится в будущем:

const future = new Date(Date.now() + 1000 * 60 * 60 * 24);

console.log(formatDistanceToNow(future));

Результат:

"in about 1 day"

Параметры options

addSuffix

Добавляет контекст «в прошлом» или «в будущем».

formatDistanceToNow(new Date(2024, 0, 1), {
  addSuffix: true
});

Результат:

"about 2 years ago"

Без addSuffix функция возвращает только длительность:

"about 2 years"

includeSeconds

Позволяет учитывать интервалы менее минуты.

formatDistanceToNow(new Date(Date.now() - 30 * 1000), {
  includeSeconds: true,
  addSuffix: true
});

Результат:

"less than 20 seconds ago"

locale

Поддержка локализации через объект локали:

import { ru } from 'date-fns/locale';

formatDistanceToNow(new Date(2023, 0, 1), {
  locale: ru,
  addSuffix: true
});

Результат:

"около 3 лет назад"

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

Функция использует приближённые значения времени:

  • 44 секунды → «less than a minute»
  • 89 секунд → «1 minute»
  • 89 минут → «1 hour»
  • 21 час → «1 day»
  • 30 дней → «about 1 month»

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


formatDistanceToNowStrict

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

Базовая сигнатура

formatDistanceToNowStrict(date, options)

Ключевое отличие

  • formatDistanceToNow → использует приблизительные формулировки («about», «over», «almost»)
  • formatDistanceToNowStrict → возвращает точное значение без размытых оценок

Пример использования

import { formatDistanceToNowStrict } from 'date-fns';

formatDistanceToNowStrict(new Date(Date.now() - 60 * 1000));

Результат:

"1 minute"

Без слов «about» или других уточняющих конструкций.

addSuffix

Работает аналогично, но сохраняет строгий формат:

formatDistanceToNowStrict(new Date(Date.now() - 3600 * 1000), {
  addSuffix: true
});

Результат:

"1 hour ago"

unit — управление единицей измерения

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

formatDistanceToNowStrict(new Date(Date.now() - 3600 * 1000), {
  unit: 'minute'
});

Результат:

"60 minutes"

Возможные значения unit:

  • "second"
  • "minute"
  • "hour"
  • "day"
  • "month"
  • "year"

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

roundingMethod

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

formatDistanceToNowStrict(new Date(Date.now() - 90 * 1000), {
  unit: 'minute',
  roundingMethod: 'floor'
});

Поведение:

  • floor — округление вниз
  • ceil — округление вверх
  • round — стандартное математическое округление

Пример различий:

  • 90 секунд →

    • floor → “1 minute”
    • ceil → “2 minutes”

includeSeconds

В строгой версии также поддерживаются секунды:

formatDistanceToNowStrict(new Date(Date.now() - 45 * 1000), {
  includeSeconds: true
});

Результат:

"45 seconds"

Сравнение поведения функций

Формулировки результата

Сценарий formatDistanceToNow formatDistanceToNowStrict
90 секунд about 1 minute 1 minute
20 часов about 1 day 20 hours
30 дней about 1 month 30 days

Логика округления

  • Первая функция оптимизирует восприятие человеком
  • Вторая функция обеспечивает точность и предсказуемость

Практические сценарии применения

Интерфейсы с высокой динамикой обновлений

formatDistanceToNow(new Date(message.createdAt), {
  addSuffix: true
});

Используется для отображения времени сообщений, комментариев, уведомлений.

Логирование и аналитика

formatDistanceToNowStrict(eventDate, {
  unit: 'minute'
});

Подходит для систем, где важна точность интервалов.

Таймеры и обратный отсчёт

formatDistanceToNowStrict(deadline, {
  addSuffix: true,
  unit: 'hour'
});

Позволяет фиксировать поведение без неоднозначных округлений.


Поведение с разными диапазонами времени

Секунды

  • formatDistanceToNow → «less than a minute»
  • formatDistanceToNowStrict → «30 seconds»

Минуты

  • «about 1 hour» vs «60 minutes»

Дни

  • «about 1 month» vs «30 days»

Годы

  • «over 2 years» vs «2 years»

Локализация и различия языков

Обе функции полностью поддерживают локали Date-fns.

import { ru } from 'date-fns/locale';

formatDistanceToNowStrict(new Date(2020, 0, 1), {
  locale: ru,
  addSuffix: true
});

Результат:

"4 года назад"

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


Влияние временной зоны и текущего времени

Обе функции всегда используют текущее системное время как точку отсчёта. Это означает:

  • результат зависит от момента вызова
  • повторный вызов через минуту изменяет результат
  • при тестировании требуется фиксация времени (mock Date)
const now = new Date(2026, 0, 1);

Типичные различия в UX-поведении

formatDistanceToNow

Используется в случаях, где важна естественность языка:

  • ленты новостей
  • социальные сети
  • чаты
  • уведомления

Особенность: допускает неточность ради читабельности

formatDistanceToNowStrict

Используется в системах, где важна интерпретация без двусмысленности:

  • админ-панели
  • аналитика
  • системные логи
  • таймеры и дедлайны

Особенность: исключает размытые формулировки