В JavaScript библиотека Moment.js предоставляет гибкие инструменты для работы с датами и временем. Одной из часто используемых возможностей является вычисление разницы между датами с учётом определённой гранулярности. Гранулярность позволяет указать единицу измерения, в которой будет возвращён результат — дни, месяцы, часы, минуты и т.д.
diff()Основной инструмент для вычисления разницы — метод
diff(), который доступен для объектов
Moment. Синтаксис метода выглядит следующим образом:
momentA.diff(momentB, unit, float)
momentA — объект Moment, от которого
производится вычитание.momentB — объект Moment, который
вычитается.unit (необязательный) —
единица измерения результата. Возможные значения: "years",
"months", "weeks", "days",
"hours", "minutes", "seconds",
"milliseconds".float (необязательный) —
логическое значение. Если true, метод вернёт дробное число
с учётом частичных единиц. По умолчанию — false, результат
округляется до целого числа в сторону меньшего значения.Пример вычисления разницы в днях:
const date1 = moment("2026-05-21");
const date2 = moment("2026-04-15");
const daysDiff = date1.diff(date2, "days");
console.log(daysDiff); // 36
Если требуется более точная разница с дробными днями:
const daysDiffFloat = date1.diff(date2, "days", true);
console.log(daysDiffFloat); // 36.0
Разница в месяцах и годах может быть сложнее, так как месяцы и годы имеют разную длину. Moment.js учитывает это автоматически, вычисляя месяцы и годы на основе календарной разницы, а не фиксированного количества дней.
const start = moment("2026-01-31");
const end = moment("2026-03-01");
console.log(end.diff(start, "months")); // 1
console.log(end.diff(start, "days")); // 29
Здесь важно понимать, что разница в месяцах не всегда равна разнице в днях, так как месяцы имеют разную длину.
Дробные значения полезны для анализа длительности событий, где требуется более высокая точность:
const start = moment("2026-05-01T08:00:00");
const end = moment("2026-05-01T12:30:00");
const hoursDiff = end.diff(start, "hours", true);
console.log(hoursDiff); // 4.5
Если установить третий параметр false (по умолчанию),
результат будет округлён до целого числа:
const hoursDiffInt = end.diff(start, "hours");
console.log(hoursDiffInt); // 4
Moment.js позволяет учитывать несколько уровней гранулярности при
вычислении разницы, комбинируя методы diff() с
манипуляциями через duration(). Например, можно получить
разницу в годах, месяцах и днях:
const start = moment("2024-02-15");
const end = moment("2026-05-21");
const duration = moment.duration(end.diff(start));
console.log(duration.years()); // 2
console.log(duration.months()); // 3
console.log(duration.days()); // 6
Здесь метод duration() создаёт объект длительности,
который автоматически разбивает разницу на компоненты лет,
месяцев, дней, часов, минут, секунд и миллисекунд.
Иногда требуется учитывать только целые календарные единицы, игнорируя частичные:
const start = moment("2026-01-31");
const end = moment("2026-03-01");
const monthsDiff = end.diff(start, "months", false);
console.log(monthsDiff); // 1
Если бы использовался третий параметр true, результат
мог бы быть дробным, отражая частичный месяц.
При вычислении разницы важно учитывать часовой пояс, особенно для единиц, меньших дня. Moment.js позволяет работать с моментами в локальном или UTC времени.
const startUTC = moment.utc("2026-05-21T23:00:00Z");
const endUTC = moment.utc("2026-05-22T01:00:00Z");
console.log(endUTC.diff(startUTC, "hours")); // 2
При работе с локальными моментами, переход на летнее/зимнее время может повлиять на результат:
const startLocal = moment("2026-03-28T01:30:00"); // Переход на летнее время
const endLocal = moment("2026-03-28T03:30:00");
console.log(endLocal.diff(startLocal, "hours")); // 1 вместо 2
Использование гранулярности в Moment.js позволяет получить
точные и удобные измерения разницы между датами,
учитывать частичные единицы и корректно работать с календарными
особенностями. Методы diff() и duration()
предоставляют полный набор инструментов для анализа временных интервалов
на любой уровень детализации.