Расчёт длительности периодов в Day.js строится вокруг операции
вычисления разницы между двумя моментами времени. Основной инструмент —
метод diff(), который возвращает количество единиц времени
между датами.
import dayjs from 'dayjs';
const start = dayjs('2026-01-01');
const end = dayjs('2026-01-10');
const days = end.diff(start, 'day');
Метод принимает два ключевых параметра: начальную дату и единицу измерения. Поддерживаются стандартные единицы времени:
Ключевая особенность: diff() по
умолчанию возвращает целое число, отбрасывая дробную часть.
end.diff(start, 'day'); // 9
Если требуется более точный результат, используется третий параметр — точность округления.
end.diff(start, 'day', true); // 9.0
Выбор единицы измерения критически влияет на результат вычисления длительности.
const a = dayjs('2026-01-01T00:00:00');
const b = dayjs('2026-01-02T12:00:00');
b.diff(a, 'day'); // 1
b.diff(a, 'hour'); // 36
b.diff(a, 'minute'); // 2160
При переходе к более крупным единицам времени происходит усечение результата. Это важно учитывать при расчётах, где требуется учитывать неполные периоды.
Месяцы и годы в календаре имеют переменную длину, поэтому расчёт длительности в этих единицах требует осторожности.
const a = dayjs('2026-01-31');
const b = dayjs('2026-02-28');
b.diff(a, 'month'); // 0
Хотя календарно прошло почти 1 месяц, результат равен 0, поскольку Day.js считает только завершённые месячные циклы.
Аналогично с годами:
dayjs('2027-01-01').diff(dayjs('2026-12-31'), 'year'); // 0
Такая модель полезна для бухгалтерских и контрактных расчётов, где важны завершённые периоды.
Для более гибкого анализа используется дробная форма:
const diff = b.diff(a, 'day', true);
Это позволяет получить точное значение с плавающей точкой, полезное для аналитики и визуализаций.
При расчёте длительности периодов часто требуется нормализация границ интервала.
const start = dayjs('2026-01-15').startOf('month');
const end = dayjs('2026-01-15').endOf('month');
const days = end.diff(start, 'day');
Методы:
startOf(unit) — приводит дату к началу периодаendOf(unit) — приводит дату к концу периодаПрименение важно при расчётах календарных интервалов: месяц, квартал, неделя.
Расчёт длительности часто сопровождается разбиением интервала на шаги.
let cursor = dayjs('2026-01-01');
const end = dayjs('2026-01-10');
while (cursor.isBefore(end)) {
cursor = cursor.add(1, 'day');
}
Такой подход используется при построении графиков, календарей и систем учёта времени.
При работе с длительностями критично учитывать влияние часовых поясов.
Для стабильных вычислений применяется плагин UTC:
import utc from 'dayjs/plugin/utc';
dayjs.extend(utc);
const a = dayjs.utc('2026-03-29T00:00:00Z');
const b = dayjs.utc('2026-03-30T00:00:00Z');
b.diff(a, 'day'); // 1
Без нормализации к UTC возможны смещения из-за переходов на летнее/зимнее время.
DST (Daylight Saving Time) создаёт интервалы, которые не равны 24 часам.
const a = dayjs('2026-03-28T00:00:00');
const b = dayjs('2026-03-29T00:00:00');
b.diff(a, 'day'); // может быть 1, но фактически не 24 часа
При расчёте точной длительности в часах лучше использовать:
b.diff(a, 'hour');
Для работы с длительностями как с отдельными объектами применяется
plugin duration.
import duration from 'dayjs/plugin/duration';
dayjs.extend(duration);
const diffMs = end.diff(start);
const d = dayjs.duration(diffMs);
Объект duration позволяет:
d.asDays(); // общее число дней (с дробью)
d.asHours(); // часы
d.minutes(); // минуты компонента
Day.js не имеет встроенного универсального форматтера, поэтому используется комбинация методов:
const d = dayjs.duration(end.diff(start));
const result = {
days: Math.floor(d.asDays()),
hours: d.hours(),
minutes: d.minutes()
};
Такой подход используется в системах отображения времени работы, логирования и аналитики.
Типичный сценарий — вычисление возраста или стажа.
const birth = dayjs('1995-06-10');
const now = dayjs();
const years = now.diff(birth, 'year');
const months = now.diff(birth.add(years, 'year'), 'month');
Комбинирование единиц позволяет получить более точную структуру периода.
При расчёте подписок важна работа с календарными циклами.
const start = dayjs('2026-01-15');
const next = start.add(1, 'month');
const days = next.diff(start, 'day');
Здесь длительность может варьироваться (28–31 день), поэтому расчёт через месяцы предпочтительнее фиксированных дней.
При необходимости деления периода на равные части используется
комбинация diff и add.
const start = dayjs('2026-01-01');
const end = dayjs('2026-02-01');
const totalDays = end.diff(start, 'day');
const step = totalDays / 4;
const segments = [];
for (let i = 0; i <= 4; i++) {
segments.push(start.add(step * i, 'day'));
}
Такой подход используется в аналитике и распределении нагрузки.
При расчётах периодов часто возникает вопрос: включается ли конечная точка.
const diff = end.diff(start, 'day');
const inclusive = diff + 1;
Day.js по умолчанию использует полуоткрытый интервал: начало включается, конец исключается.
Для систем учёта времени корректная стратегия расчёта длительности строится на следующих принципах:
diff() только для измерения, а не
генерации интерваловstartOf() и endOf() для
календарных границmonth и year в аналитических
расчётах без понимания их дискретностиПри обработке больших массивов дат важно минимизировать создание объектов Day.js.
for (let i = 0; i < dates.length; i++) {
const diff = dayjs(dates[i]).diff(base, 'day');
}
Более эффективный подход — предобработка базовых значений и повторное использование объектов, где это возможно.
Комбинированные сценарии часто требуют последовательных преобразований:
const start = dayjs('2026-01-01');
const checkpoint = start.add(10, 'day');
const end = start.add(2, 'month');
const firstPhase = checkpoint.diff(start, 'day');
const secondPhase = end.diff(checkpoint, 'day');
Такой подход используется в моделях жизненного цикла процессов и проектных диаграммах.