formatDistanceStrict для точных интервалов

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

Основная цель — получение максимально точного, предсказуемого результата: «2 дня», «3 месяца», «7 минут», без перехода к более крупным или приблизительным единицам.


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

formatDistanceStrict(date, baseDate, [options])

Параметры

  • date — целевая дата, относительно которой вычисляется интервал
  • baseDate — базовая дата сравнения
  • options — объект настроек форматирования

Возвращаемое значение — строка с точным описанием разницы.


Принцип работы

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

Ключевой принцип:

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

Пример логики:

  • 1.9 дня → «1 day»
  • 59 seconds → «59 seconds»
  • 61 seconds → «1 minute» (так как 61 / 60 = 1.01 → строгая нормализация к минутам)

Отличие от formatDistance

Главное различие между formatDistanceStrict и formatDistance заключается в правилах округления и интерпретации интервалов.

formatDistance

  • допускает естественное языковое округление
  • может возвращать «about 1 hour», «less than a minute»
  • ориентирован на человекочитаемость

formatDistanceStrict

  • исключает приблизительные формулировки
  • не использует «about», «almost», «less than»
  • возвращает строго числовую единицу

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

formatDistance(date1, date2);
// about 1 hour

formatDistanceStrict(date1, date2);
// 59 minutes

Поддерживаемые единицы времени

Функция автоматически выбирает одну из следующих единиц:

  • seconds
  • minutes
  • hours
  • days
  • months
  • years

Выбор зависит от величины интервала.


Основные опции

addSuffix

Добавляет направление относительности даты.

formatDistanceStrict(new Date(2026, 0, 1), new Date(2025, 0, 1), {
  addSuffix: true
});

Результат:

"in 1 year"

Без addSuffix:

"1 year"

roundingMethod

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

Доступные значения:

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

Пример:

formatDistanceStrict(new Date(2025, 0, 2), new Date(2025, 0, 1), {
  roundingMethod: "ceil"
});

Если разница составляет 1.1 дня, результат будет округлён до:

2 days

locale

Позволяет локализовать вывод.

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

formatDistanceStrict(date1, date2, { locale: ru });

В этом случае результат будет на русском языке:

"1 день"

Поведение на границах единиц

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

Секунды → минуты

  • 59 секунд → “59 seconds”
  • 60 секунд → “1 minute”

Минуты → часы

  • 59 минут → “59 minutes”
  • 60 минут → “1 hour”

Часы → дни

  • 23 часа → “23 hours”
  • 24 часа → “1 day”

Дни → месяцы

Месяцы вычисляются на основе календарных различий, а не фиксированного количества дней, что важно учитывать:

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

Работа с отрицательными интервалами

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

formatDistanceStrict(new Date(2025, 0, 1), new Date(2026, 0, 1));

Результат:

"1 year"

При добавлении addSuffix: true:

"1 year ago"

Использование в реальных сценариях

Таймлайны событий

Используется для отображения времени до или после события без неоднозначности.

formatDistanceStrict(eventDate, new Date(), { addSuffix: true });

Результат:

"3 days ago"

Логи и аудит

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

formatDistanceStrict(logEnd, logStart);

Пример:

"14 minutes"

Интерфейсы уведомлений

В уведомлениях важно избегать размытых формулировок:

  • вместо «about 1 hour ago»
  • используется «59 minutes ago» или «1 hour ago»

Особенности вычисления месяцев и лет

В отличие от фиксированных единиц (секунды, минуты, часы), месяцы и годы зависят от календаря.

Пример:

  • 1 января → 1 февраля = 1 month
  • 31 января → 28 февраля = 1 month (в зависимости от года)

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


Ограничения и нюансы

  • не предназначена для высокоточного измерения времени в миллисекундах
  • не учитывает временные зоны напрямую (работает с объектами Date)
  • календарные месяцы могут иметь разную длину
  • строгая логика может отличаться от пользовательских ожиданий в крайних случаях

Сравнение поведения округления

Интервал formatDistanceStrict formatDistance
59 сек 59 seconds less than a minute
61 сек 1 minute about 1 minute
119 сек 1 minute about 2 minutes
23 ч 23 hours about 1 day
25 ч 1 day about 1 day

Типичные ошибки при использовании

Ожидание «гибкости»

Попытка использовать функцию для «разговорных» интерфейсов приводит к слишком сухим формулировкам.

Игнорирование календарной природы месяцев

Предположение, что 30 дней всегда равны месяцу, приводит к несоответствиям.

Смешивание с форматированием дат

Функция не форматирует абсолютные даты, только интервалы.


Поведение при малых интервалах

При минимальных значениях:

formatDistanceStrict(new Date(), new Date());

Результат:

"0 seconds"

Если интервал менее одной секунды, округление зависит от roundingMethod.


Итоговая модель поведения

formatDistanceStrict строится на трёх принципах:

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

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