formatDuration для временных интервалов

Функция formatDuration из библиотеки date-fns предназначена для преобразования объекта временной длительности в человекочитаемую строку. Она работает с разложенными по единицам времени значениями и формирует компактное или расширенное текстовое представление интервала.

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

{
  years: 1,
  months: 2,
  days: 3,
  hours: 4,
  minutes: 5,
  seconds: 6
}

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


Сигнатура и базовый принцип работы

formatDuration(duration, options?)
  • duration — объект длительности с числовыми полями
  • options — параметры форматирования

Результатом является строка, составленная из непустых единиц времени.

Простейший пример:

import { formatDuration } from 'date-fns';

formatDuration({
  hours: 1,
  minutes: 30,
  seconds: 15
});

Результат:

"1 hour, 30 minutes, 15 seconds"

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

Функция работает только с фиксированным набором ключей:

  • years
  • months
  • weeks (в некоторых версиях может отсутствовать или не поддерживаться напрямую)
  • days
  • hours
  • minutes
  • seconds

Любые дополнительные поля игнорируются.

Пример:

formatDuration({
  years: 2,
  days: 10,
  minutes: 0,
  customField: 999
});

Результат:

"2 years, 10 days"

Исключение нулевых значений

По умолчанию нулевые единицы не включаются в результат. Это делает строку компактной и читаемой.

formatDuration({
  hours: 0,
  minutes: 5,
  seconds: 0
});

Результат:

"5 minutes"

Для изменения поведения используется опция zero.


Опция zero

Опция zero позволяет включать значения, равные нулю.

formatDuration(
  {
    hours: 0,
    minutes: 5,
    seconds: 0
  },
  { zero: true }
);

Результат:

"0 hours, 5 minutes, 0 seconds"

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


Управление порядком вывода через format

Опция format задаёт порядок и набор отображаемых единиц.

formatDuration(
  {
    days: 2,
    hours: 3,
    minutes: 10
  },
  { format: ['hours', 'minutes'] }
);

Результат:

"3 hours, 10 minutes"

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


Разделитель между единицами

По умолчанию элементы строки разделяются запятой и пробелом:

", "

Это поведение можно изменить через delimiter.

formatDuration(
  {
    hours: 1,
    minutes: 20,
    seconds: 5
  },
  { delimiter: ' | ' }
);

Результат:

"1 hour | 20 minutes | 5 seconds"

Локализация вывода

Поддержка локализации реализуется через параметр locale. Он влияет на склонения и форму слов.

Пример с условной локалью:

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

formatDuration(
  {
    hours: 1,
    minutes: 21
  },
  { locale: ru }
);

Результат будет зависеть от локализации:

"1 час, 21 минута"

Локализация важна для корректного грамматического оформления чисел и единиц времени.


Формирование длительности через intervalToDuration

На практике formatDuration часто используется вместе с intervalToDuration, который преобразует разницу между датами в объект длительности.

import { intervalToDuration, formatDuration } from 'date-fns';

const duration = intervalToDuration({
  start: new Date(2020, 0, 1),
  end: new Date(2023, 5, 15)
});

formatDuration(duration);

В результате получается строковое представление интервала между датами без ручного расчёта единиц времени.


Особенности округления и нормализации

formatDuration не выполняет математического преобразования единиц. Функция не переводит, например, 90 минут в 1 час 30 минут.

Если передать:

{
  hours: 0,
  minutes: 90
}

результат останется:

"90 minutes"

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


Пустые объекты и поведение результата

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

formatDuration({});

Результат:

""

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


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

Формирование длительности активности:

formatDuration({
  hours: 2,
  minutes: 45
});

Отображение времени работы таймера:

formatDuration({
  minutes: 3,
  seconds: 12
});

Показ длительности события:

formatDuration({
  days: 1,
  hours: 6,
  minutes: 30
});

Композиция с другими функциями date-fns

formatDuration часто используется как финальный шаг цепочки обработки времени:

  1. вычисление интервала
  2. нормализация в объект длительности
  3. форматирование в строку

Пример композиции:

import { differenceInSeconds, formatDuration } from 'date-fns';

const diff = differenceInSeconds(
  new Date(2024, 0, 1),
  new Date(2023, 0, 1)
);

formatDuration({
  years: Math.floor(diff / (60 * 60 * 24 * 365))
});

Ограничения функции

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

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


Структура выходной строки

Финальная строка формируется по следующему принципу:

  1. отбор ненулевых значений (если zero: false)
  2. сортировка по порядку единиц
  3. применение локализации (если задана)
  4. объединение через delimiter

Результат всегда детерминирован при одинаковых входных данных и настройках.