В библиотеке Luxon интервал представляет собой непрерывный отрезок времени между двумя точками — началом и концом. Эта модель используется для задач планирования, анализа пересечений событий, расчёта длительностей и построения временных диапазонов.
Интервалы реализованы классом Interval, который
оперирует объектами DateTime и предоставляет набор методов
для геометрии времени: пересечения, объединения, разбиения и проверки
включений.
Базовая форма интервала задаётся двумя моментами времени:
import { DateTime, Interval } from "luxon";
const start = DateTime.fromISO("2026-01-01T10:00:00");
const end = DateTime.fromISO("2026-01-01T12:00:00");
const interval = Interval.fromDateTimes(start, end);
Ключевое требование: начало должно быть не позже конца. При нарушении этого условия интервал становится невалидным.
Дополнительные способы создания:
const interval = Interval.fromISO("2026-01-01T10:00:00/2026-01-01T12:00:00");
const now = DateTime.now();
const interval = Interval.after(now, { hours: 2 });
const interval = Interval.before(now, { days: 1 });
Интервал содержит свойства start, end и
флаг валидности:
interval.isValid;
interval.start;
interval.end;
Проверка корректности используется при обработке динамических данных:
if (!interval.isValid) {
// обработка некорректного диапазона
}
Длительность интервала вычисляется относительно единиц времени:
interval.length("hours");
interval.length("minutes");
interval.length("days");
Результат зависит от календаря и часовых поясов, поскольку
используется модель DateTime.
Метод contains определяет, входит ли точка во временной
диапазон:
interval.contains(DateTime.fromISO("2026-01-01T11:00:00"));
Семантика включает начало и исключает конец:
[start, end).
Проверка наличия пересечения:
interval1.overlaps(interval2);
Метод возвращает true, если диапазоны имеют хотя бы одну
общую точку.
Формирование нового интервала из общей части:
const common = interval1.intersection(interval2);
Если пересечения нет, результатом становится null.
Объединение возможно при пересечении или соприкосновении:
const merged = interval1.union(interval2);
Если интервалы не связаны, результатом становится массив интервалов.
Метод merge объединяет массив интервалов:
const result = Interval.merge([i1, i2, i3]);
Соседние и пересекающиеся диапазоны объединяются в минимальное количество непрерывных отрезков.
Операция XOR возвращает части, не входящие в пересечение:
const diff = interval1.xor(interval2);
Результатом становится массив интервалов, отражающих «исключённые» области.
interval1.engulfs(interval2);
Истинно, если второй интервал целиком содержится внутри первого.
interval1.abutsStart(interval2);
interval1.abutsEnd(interval2);
Используется для проверки соприкосновения без пересечения.
const parts = interval.splitAt(DateTime.fromISO("2026-01-01T11:00:00"));
Интервал делится в указанных точках на несколько частей.
const chunks = interval.splitBy({ minutes: 30 });
Создаются равные сегменты заданной длительности.
Метод mapEndpoints позволяет преобразовать границы
интервала:
const shifted = interval.mapEndpoints(
dt => dt.plus({ hours: 1 }),
dt => dt.plus({ hours: 1 })
);
Применяется для синхронного смещения начала и конца.
Метод set создаёт новый интервал с изменёнными
параметрами:
const upd ated = interval.se t({
start: start.plus({ hours: 1 })
});
Оригинальный интервал остаётся неизменным.
Интервал может быть использован как основа для генерации
последовательностей времени через разбиение и длину шагов. Комбинация
splitBy и count позволяет строить дискретные
временные сетки.
Строковое представление:
interval.toISO();
Пример результата:
2026-01-01T10:00:00.000Z/2026-01-01T12:00:00.000Z
Также доступны специализированные форматы:
interval.toISODate();
interval.toISOTime();
Множественные интервалы часто нормализуются через:
merge — объединение пересекающихсяxor — выделение разницыunion — объединение двух интерваловТипичный сценарий обработки расписаний:
const busy = Interval.merge(meetings);
const free = busy.xor(workDayInterval);
При работе с несколькими диапазонами важна приоритизация:
Эти свойства позволяют моделировать календарные системы, бронирования и временные очереди без дискретизации времени.
Интервалы зависят от DateTime, поэтому при смене
временной зоны границы могут смещаться. Корректная модель требует
фиксированного контекста времени (UTC или единый zoneId), иначе операции
пересечения могут давать неожиданные результаты.
Интервал обязан иметь обе границы. Отсутствие одной из них приводит к
невалидному состоянию. Для открытых диапазонов используется комбинация с
Infinity логикой на уровне приложения, а не внутри
класса.
Комбинирование методов формирует сложные преобразования:
const available = Interval
.merge(busyIntervals)
.xor(workInterval)
.map(i => i.set({ start: i.start.plus({ minutes: 15 }) }));
Такие цепочки позволяют строить системы расписаний с учётом буферов, задержек и ограничений ресурсов.