Функция formatDistance из библиотеки
date-fns предназначена для преобразования разницы между
двумя датами в человекочитаемое выражение, отражающее относительную
длительность: «около 5 минут», «2 месяца», «менее 10 секунд». Основная
цель — представление временного интервала в естественной языковой форме
без ручной обработки единиц времени.
Функция имеет следующий вид:
formatDistance(date, baseDate, [options])
Параметры:
date — дата, расстояние до которой вычисляетсяbaseDate — базовая дата для сравненияoptions — объект конфигурации (опционально)Возвращаемое значение — строка, описывающая расстояние между датами.
formatDistance сначала определяет абсолютную разницу
между датами, затем подбирает наиболее подходящую единицу измерения:
После этого результат округляется до наиболее «естественного» значения и преобразуется в текст.
Пример логики:
import { formatDistance } from 'date-fns';
const result = formatDistance(
new Date(2024, 0, 1),
new Date(2024, 0, 5)
);
console.log(result);
Результат:
"4 days"
Функция всегда возвращает относительное расстояние, а не абсолютную разницу в конкретной единице.
Порядок аргументов влияет на смысл результата. Разница всегда
считается как расстояние от baseDate к
date.
formatDistance(
new Date(2024, 0, 10),
new Date(2024, 0, 1)
);
Результат:
"9 days"
Если даты поменять местами, текст останется тем же, но смысл в сочетании с суффиксом может измениться при использовании опций.
Опция addSuffix добавляет контекст относительности:
«ago» или «in».
import { formatDistance } from 'date-fns';
const past = formatDistance(
new Date(2024, 0, 1),
new Date(2024, 0, 10),
{ addSuffix: true }
);
console.log(past);
Результат:
"9 days ago"
А для будущего времени:
formatDistance(
new Date(2024, 0, 10),
new Date(2024, 0, 1),
{ addSuffix: true }
);
"in 9 days"
Для очень малых разниц используется приближение:
formatDistance(
new Date(2024, 0, 1, 12, 0, 30),
new Date(2024, 0, 1, 12, 0, 0)
);
Результат:
"less than a minute"
При увеличении интервала до минут и секунд функция начинает округлять значения:
date-fns поддерживает локализацию через объект
locale.
import { formatDistance } from 'date-fns';
import { ru } from 'date-fns/locale';
formatDistance(
new Date(2024, 0, 10),
new Date(2024, 0, 1),
{ locale: ru }
);
Результат:
"9 дней"
Локализация влияет не только на перевод слов, но и на грамматические формы числительных, что особенно важно для языков с падежной системой.
В локализованных версиях учитываются:
Например:
Эти различия полностью контролируются внутренними правилами локали, без необходимости ручной обработки.
В библиотеке существует альтернативная функция:
formatDistanceformatDistanceStrictИспользует приближённые выражения:
Использует точные значения:
import { formatDistanceStrict } from 'date-fns';
formatDistanceStrict(
new Date(2024, 0, 1),
new Date(2024, 0, 2)
);
Результат:
"1 day"
Различие заключается в стиле:
formatDistance — разговорная формаformatDistanceStrict — точная формулировка без «about»,
«over», «less than»Функция использует систему приближений:
| Интервал | Результат |
|---|---|
| < 30 сек | less than a minute |
| 30–90 сек | 1 minute |
| 90 сек – 45 мин | X minutes |
| 45–90 мин | about 1 hour |
| 90 мин – 22 ч | X hours |
| 22–36 ч | 1 day |
| 36 ч – 25 д | X days |
| 25–45 д | about 1 month |
| 45–345 д | X months |
| 345–547 д | about 1 year |
Эта система обеспечивает читаемость, но не точность.
Если переданы некорректные даты:
Invalid Dateundefinednullповедение может привести к выбросу исключения или возвращению некорректного результата в зависимости от версии библиотеки.
Рекомендуется предварительная валидация через:
isValidparseISOformatDistance часто применяется в интерфейсах, где
важно отображение динамического времени:
При этом функция используется совместно с
addSuffix: true, формируя законченные фразы без
дополнительной обработки.
При динамическом обновлении интерфейса значение может пересчитываться периодически:
setInterval(() => {
console.log(
formatDistance(new Date(), pastDate, { addSuffix: true })
);
}, 60000);
Такая схема позволяет поддерживать актуальность отображаемого времени без ручных пересчётов единиц.
При работе с многолетними интервалами функция переходит к годам и месяцам:
formatDistance(
new Date(2010, 0, 1),
new Date(2024, 0, 1)
);
Результат:
"about 14 years"
Использование слова «about» отражает внутреннее округление и приближенность расчёта.
В практических сценариях formatDistance часто
используется вместе с:
parseISO — парсинг строк датdifferenceInDays — точные расчётыformat — форматирование абсолютных датsubDays, addDays — арифметика датПример комбинирования:
import { formatDistance, parseISO } from 'date-fns';
const date = parseISO('2024-01-10T12:00:00Z');
formatDistance(date, new Date(), { addSuffix: true });
При массовом использовании следует учитывать:
Оптимизация обычно достигается через:
Особое внимание уделяется переходным состояниям:
Такая модель сглаживает восприятие времени и уменьшает «скачки» значений.
Основные доступные опции:
addSuffix — добавление «ago / in»locale — выбор языка и правил форматированияДополнительные настройки напрямую в formatDistance
ограничены, поскольку библиотека ориентирована на стандартизированное
поведение.
Функция работает с объектами Date, поэтому:
При работе с UTC-строками рекомендуется предварительный парсинг через ISO-форматы.
formatDistance(eventDate, new Date(), { addSuffix: true });
formatDistance(new Date(), eventDate, { addSuffix: true });
formatDistance(date1, date2);
Если даты совпадают:
formatDistance(new Date(), new Date());
Результат:
"less than a minute"
Это связано с минимальной гранулярностью измерения, которая не опускается до нуля в человекочитаемом виде.