В библиотеке date-fns функция intervalToDuration
предназначена для преобразования временного интервала между двумя датами
в структурированное представление длительности. В отличие от простого
вычисления разницы в миллисекундах или днях, результат возвращается в
виде объекта с разложением по календарным единицам: годам, месяцам,
дням, часам, минутам и секундам.
intervalToDuration({ start, end })
Date | number)Date | number)Оба значения могут быть объектами Date или числом
(timestamp в миллисекундах).
Функция возвращает объект следующего вида:
{
years: number,
months: number,
days: number,
hours: number,
minutes: number,
seconds: number
}
Каждое поле представляет максимально возможное целое значение соответствующей единицы времени в пределах интервала.
intervalToDuration работает не как арифметическая
разница в миллисекундах, а как календарное разложение интервала. Это
означает:
Такой подход делает результат более «человеческим», но менее линейным по сравнению с чистыми временными вычислениями.
import { intervalToDuration } from 'date-fns'
const result = intervalToDuration({
start: new Date(2023, 0, 1),
end: new Date(2025, 5, 10)
})
console.log(result)
Возможный результат:
{
years: 2,
months: 5,
days: 9,
hours: 0,
minutes: 0,
seconds: 0
}
intervalToDuration({
start: new Date(2024, 0, 1, 10, 15, 0),
end: new Date(2024, 0, 1, 12, 45, 30)
})
Результат:
{
years: 0,
months: 0,
days: 0,
hours: 2,
minutes: 30,
seconds: 30
}
intervalToDuration({
start: new Date(2024, 0, 15),
end: new Date(2024, 3, 10)
})
Результат будет учитывать разную длину месяцев:
{
years: 0,
months: 2,
days: 26,
hours: 0,
minutes: 0,
seconds: 0
}
В экосистеме date-fns существует набор функций
differenceInDays, differenceInMonths,
differenceInSeconds и т.д.
Ключевое различие:
differenceIn* возвращает разницу в одной единице
измеренияintervalToDuration раскладывает интервал сразу по всем
единицамПример:
differenceInDays(end, start) // одно число
intervalToDuration({ start, end }) // объект с разложением
Если интервал проходит через февраль, март и апрель, вычисление учитывает фактическое количество дней в каждом месяце. Это делает результат зависимым от календаря, а не от фиксированной длительности.
При переходе через февраль в високосном году учитывается дополнительный день, что влияет на итоговое разложение по дням и месяцам.
Алгоритм работает по принципу жадного разложения:
Каждый шаг уменьшает остаток интервала.
Функция автоматически:
number в Datestart > end)Пример:
intervalToDuration({
start: new Date(2025, 1, 1),
end: new Date(2024, 1, 1)
})
Результат будет эквивалентен нормализованному прямому интервалу.
Часто результат применяется для построения человекочитаемых строк:
const d = intervalToDuration({ start, end })
const formatted =
`${d.years}г ${d.months}м ${d.days}д ` +
`${d.hours}ч ${d.minutes}м ${d.seconds}с`
Такой подход используется в интерфейсах, где требуется точное отображение длительности, а не абстрактное количество часов или дней.
Если разница между датами отсутствует:
intervalToDuration({
start: new Date(2024, 0, 1),
end: new Date(2024, 0, 1)
})
Результат:
{
years: 0,
months: 0,
days: 0,
hours: 0,
minutes: 0,
seconds: 0
}
Объект длительности не содержит информации о «плоском» времени. Он отражает структуру календарного интервала, поэтому:
Такой формат предназначен исключительно для представления, а не для точных вычислений.