Работа с разницей между датами в Luxon строится вокруг объектов
DateTime и специализированного класса
Duration, который представляет не момент времени, а
промежуток между двумя моментами. В отличие от стандартного
Date, Luxon учитывает временные зоны, календарные
особенности и корректно работает с единицами измерения времени, что
делает вычисление разницы дат предсказуемым и точным.
Разница между датами в Luxon не возвращается в виде числа миллисекунд по умолчанию. Вместо этого результатом является объект длительности, который может быть представлен в различных единицах: днях, часах, минутах, секундах и их комбинациях.
Основной метод для вычисления разницы:
const diff = dt1.diff(dt2);
Где:
dt1 — более поздняя дата (или базовая точка
отсчёта)dt2 — более ранняя датаРезультатом является объект Duration.
import { DateTime } from "luxon";
const start = DateTime.fromISO("2026-01-01T00:00:00");
const end = DateTime.fromISO("2026-01-10T12:00:00");
const diff = end.diff(start);
По умолчанию Luxon возвращает длительность в миллисекундах, если явно не указаны единицы измерения.
Ключевая особенность diff — возможность задавать единицы
измерения разницы.
end.diff(start, ["days"]);
millisecondssecondsminuteshoursdaysweeksmonthsyearsconst diffInDays = end.diff(start, "days");
console.log(diffInDays.days);
Результат будет дробным, если разница не кратна суткам.
Luxon позволяет получать сразу несколько единиц в одном объекте длительности.
const diff = end.diff(start, ["days", "hours", "minutes"]);
Результат:
diff.days
diff.hours
diff.minutes
Важно: значения распределяются по иерархии единиц, но не нормализуются автоматически без дополнительных методов.
Для приведения результата к корректной структуре используется метод
normalize().
const diff = end.diff(start, ["days", "hours"]).normalize();
Без нормализации возможно получение значений вида:
После нормализации происходит перераспределение значений по единицам.
Частый сценарий — вычисление разницы между датой и текущим моментом.
diffNowconst dt = DateTime.fromISO("2026-12-01");
const diff = dt.diffNow("days");
Если дата в будущем — результат положительный, если в прошлом — отрицательный.
Для получения модуля разницы используется as() или
toMillis() с последующей обработкой.
const diff = Math.abs(end.diff(start).as("days"));
Или:
const diff = end.diff(start).toMillis();
const abs = Math.abs(diff);
Объект Duration может быть преобразован в
человекочитаемый вид.
toObject()const diff = end.diff(start, ["days", "hours"]);
console.log(diff.toObject());
Результат:
{ days: 9, hours: 12 }
toHuman()Метод формирует строку с автоматическим форматированием.
diff.toHuman();
Пример результата:
9 days, 12 hours
Luxon сохраняет точность при вычислении дробных интервалов.
const diff = end.diff(start, "days");
console.log(diff.days); // например 9.5
Это особенно важно при:
Разница дат всегда вычисляется с учётом временной зоны объектов
DateTime.
const a = DateTime.fromISO("2026-01-01T00:00", { zone: "Europe/Paris" });
const b = DateTime.fromISO("2026-01-01T00:00", { zone: "UTC" });
const diff = a.diff(b, "hours");
Разница может отличаться от ожиданий при игнорировании таймзон, так как Luxon приводит значения к абсолютному времени внутри системы UTC.
diff и
untilМетод until является альтернативой:
const interval = start.until(end);
Разница:
diff → возвращает Durationuntil → возвращает IntervalДалее:
interval.length("days");
Interval удобен для анализа диапазонов, а
Duration — для арифметики времени.
Месяцы и годы не фиксированы по длительности:
Поэтому:
end.diff(start, "months");
может давать неравномерные результаты при конвертации в дни.
При использовании комбинаций единиц важно учитывать порядок нормализации:
end.diff(start, ["months", "days"]).normalize();
Без нормализации часть данных может оставаться “переполненной”.
Порядок аргументов критичен:
a.diff(b)
и
b.diff(a)
дают одинаковую величину, но с разным знаком.
const birth = DateTime.fromISO("2000-05-10");
const age = DateTime.now().diff(birth, "years").years;
const event = DateTime.fromISO("2026-12-31T23:59");
const remaining = event.diffNow(["days", "hours", "minutes"]);
const start = DateTime.fromISO("2026-05-23T09:00");
const end = DateTime.fromISO("2026-05-23T18:30");
const work = end.diff(start, "hours").hours;
const first = DateTime.fromISO("2026-01-01");
const second = DateTime.fromISO("2026-06-01");
const diff = second.diff(first, ["days"]);
Используется для:
diff.as("milliseconds");
diff.as("seconds");
diff.as("hours");
Стандартный подход:
const diff = (end - start) / (1000 * 60 * 60 * 24);
Luxon:
end.diff(start, "days").days;
Различия:
Для контроля точности используется округление:
const diff = end.diff(start, "days").mapUnits(x => Math.floor(x));
Это позволяет фиксировать:
Luxon не ограничивает направление разницы:
const diff = start.diff(end, "days");
Результат будет отрицательным Duration, что полезно
для: