В Day.js вычисление разницы между двумя моментами времени выполняется
методом diff(). Его базовая форма:
dayjs(end).diff(dayjs(start), unit)
Результат зависит от выбранной единицы измерения и всегда возвращается как число, представляющее количество целых единиц между датами, если не указано обратное.
Поддерживаемые единицы:
millisecondsecondminutehourdayweekmonthyearНаиболее точный способ сравнения временных точек — использование миллисекунд.
const start = dayjs('2026-01-01T00:00:00.000');
const end = dayjs('2026-01-01T00:00:01.250');
const diff = end.diff(start, 'millisecond');
Результат будет:
1250
Разница в миллисекундах всегда линейна и не зависит от календарных особенностей.
При переходе к более крупным единицам Day.js автоматически выполняет усечение дробной части.
const start = dayjs('2026-01-01T00:00:00');
const end = dayjs('2026-01-01T00:05:30');
end.diff(start, 'second'); // 330
end.diff(start, 'minute'); // 5
end.diff(start, 'hour'); // 0
Особенность поведения:
Для получения дробного результата используется третий аргумент:
end.diff(start, 'minute', true); // 5.5
Работа с днями учитывает календарную структуру, но не временные зоны напрямую.
const start = dayjs('2026-01-01');
const end = dayjs('2026-01-10');
end.diff(start, 'day'); // 9
Важно учитывать, что метод считает разницу как количество полных переходов границы дня.
Неделя интерпретируется как 7 дней без учета локальных календарных особенностей.
const start = dayjs('2026-01-01');
const end = dayjs('2026-01-22');
end.diff(start, 'week'); // 3
Каждая неделя — это строго 7 дней, без привязки к понедельнику или воскресенью.
Месяцы имеют переменную длину, что делает вычисление менее линейным.
const start = dayjs('2026-01-01');
const end = dayjs('2026-04-01');
end.diff(start, 'month'); // 3
При вычислении месяцев учитываются календарные переходы, а не фиксированное количество дней.
Пример неоднозначности:
dayjs('2026-02-28').diff(dayjs('2026-01-31'), 'month'); // 0
Причина: неполный календарный месяц не засчитывается.
Годы вычисляются как количество полных календарных циклов.
const start = dayjs('2020-01-01');
const end = dayjs('2026-01-01');
end.diff(start, 'year'); // 6
При этом високосные годы учитываются автоматически через календарную модель.
Третий аргумент diff() позволяет получать дробные
результаты.
const start = dayjs('2026-01-01T00:00:00');
const end = dayjs('2026-01-01T12:00:00');
end.diff(start, 'day', true); // 0.5
end.diff(start, 'hour', true); // 12
Поведение:
false или отсутствие аргумента → целое числоtrue → число с плавающей точкойПорядок аргументов влияет на знак результата.
dayjs('2026-01-10').diff(dayjs('2026-01-01'), 'day'); // 9
dayjs('2026-01-01').diff(dayjs('2026-01-10'), 'day'); // -9
Метод не нормализует знак, он строго отражает направление вычисления.
При использовании локального времени возможны расхождения из-за переходов времени и DST.
const a = dayjs('2026-03-29T01:00:00');
const b = dayjs('2026-03-29T03:00:00');
b.diff(a, 'hour'); // может быть 1 или 2 в зависимости от DST
Для стабильных вычислений используется UTC-плагин:
import utc from 'dayjs/plugin/utc';
dayjs.extend(utc);
const a = dayjs.utc('2026-03-29T01:00:00');
const b = dayjs.utc('2026-03-29T03:00:00');
b.diff(a, 'hour'); // 2
Часто разница используется для вычисления длины интервалов.
const startOfMonth = dayjs().startOf('month');
const endOfMonth = dayjs().endOf('month');
endOfMonth.diff(startOfMonth, 'day');
Особенность:
startOf() нормализует время к началу единицыendOf() устанавливает конец единицыЭто важно при расчёте длительности календарных периодов.
Day.js не выполняет автоматическую декомпозицию разницы, поэтому для сложных представлений используется последовательное вычитание.
const start = dayjs('2026-01-01');
const end = dayjs('2026-03-15');
const months = end.diff(start, 'month');
const days = end.diff(start.add(months, 'month'), 'day');
Такой подход позволяет строить составные интервалы: «X месяцев Y дней».
При переходах между месяцами с разным количеством дней возникают неоднозначности.
dayjs('2026-01-31').diff(dayjs('2026-02-28'), 'month'); // 0
Причина:
const a = dayjs('2026-01-01');
const b = dayjs('2026-01-01');
b.diff(a, 'day'); // 0
Метод возвращает ноль для всех единиц измерения при идентичности временных точек.
Для более сложных операций разницы часто преобразуются в объект длительности:
import duration from 'dayjs/plugin/duration';
dayjs.extend(duration);
const diff = dayjs('2026-01-10').diff(dayjs('2026-01-01'), 'hour');
const d = dayjs.duration(diff, 'hour');
Это позволяет выполнять дальнейшие операции:
Помимо diff(), используются:
isBefore()isAfter()isSame()Они не возвращают числовую разницу, но часто комбинируются с
diff() для условной логики.
if (end.isAfter(start)) {
const days = end.diff(start, 'day');
}
Игнорирование усечения дробной части
end.diff(start, 'hour'); // может потерять минутыИспользование локального времени без учета DST приводит к некорректным часовым интервалам
Предположение фиксированной длины месяца месяц не равен 30 дням
Смешивание единиц без нормализации требует явного контроля переходов
При обработке больших массивов дат:
diff() выполняется в константное времяОптимизация:
const start = dayjs('2026-01-01');
const results = dates.map(d => dayjs(d).diff(start, 'day'));
Общее правило поведения:
Эта модель обеспечивает предсказуемость в прикладных сценариях, где требуется работа с календарём, а не только с абсолютным временем.