Метод intersection

В библиотеке Luxon пересечение интервалов реализуется через метод intersection, доступный у экземпляров класса Interval. Интервалы в Luxon представляют собой отрезки времени с началом и концом, где логика работы построена на строгом сравнении границ: начальной (start) и конечной (end).

Интервалы интерпретируются как полуоткрытые отрезки вида [start, end), где начальная точка включена, а конечная — нет. Это влияет на результат пересечения, особенно при работе с соседними интервалами, которые формально не пересекаются.


Сигнатура метода

Метод вызывается у экземпляра интервала:

interval1.intersection(interval2)

Параметры

  • interval2: Interval — второй интервал, с которым выполняется операция пересечения

Возвращаемое значение

  • Interval — новый интервал, представляющий пересечение
  • null — если пересечения нет

Логика работы метода intersection

Пересечение двух интервалов — это новый интервал, который включает только ту часть времени, которая присутствует одновременно в обоих интервалах.

Для двух интервалов:

  • A = [A.start, A.end)
  • B = [B.start, B.end)

результат пересечения вычисляется как:

  • начало: max(A.start, B.start)
  • конец: min(A.end, B.end)

Если вычисленный конец меньше или равен началу, пересечения нет.


Основные сценарии поведения

1. Полное пересечение (один внутри другого)

Если один интервал полностью содержится в другом:

import { DateTime, Interval } from "luxon";

const a = Interval.fromDateTimes(
  DateTime.fromISO("2026-05-01T10:00"),
  DateTime.fromISO("2026-05-01T18:00")
);

const b = Interval.fromDateTimes(
  DateTime.fromISO("2026-05-01T12:00"),
  DateTime.fromISO("2026-05-01T14:00")
);

const result = a.intersection(b);

Результат:

[2026-05-01 12:00, 2026-05-01 14:00)

2. Частичное пересечение

const a = Interval.fromDateTimes(
  DateTime.fromISO("2026-05-01T10:00"),
  DateTime.fromISO("2026-05-01T15:00")
);

const b = Interval.fromDateTimes(
  DateTime.fromISO("2026-05-01T12:00"),
  DateTime.fromISO("2026-05-01T18:00")
);

const result = a.intersection(b);

Результат:

[2026-05-01 12:00, 2026-05-01 15:00)

3. Отсутствие пересечения

const a = Interval.fromDateTimes(
  DateTime.fromISO("2026-05-01T10:00"),
  DateTime.fromISO("2026-05-01T12:00")
);

const b = Interval.fromDateTimes(
  DateTime.fromISO("2026-05-01T12:00"),
  DateTime.fromISO("2026-05-01T14:00")
);

const result = a.intersection(b);

Результат:

null

Причина: конец первого интервала совпадает с началом второго, а полуоткрытая модель [start, end) исключает точку end.


4. Полное несовпадение

const a = Interval.fromDateTimes(
  DateTime.fromISO("2026-05-01T08:00"),
  DateTime.fromISO("2026-05-01T09:00")
);

const b = Interval.fromDateTimes(
  DateTime.fromISO("2026-05-01T10:00"),
  DateTime.fromISO("2026-05-01T11:00")
);

const result = a.intersection(b);

Результат:

null

Математическая модель пересечения

Пусть интервалы заданы как:

A = [a1, a2)
B = [b1, b2)

Тогда пересечение:

A ∩ B = [max(a1, b1), min(a2, b2))

Существование пересечения определяется условием:

max(a1, b1) < min(a2, b2)

A B = [(a_1, b_1), (a_2, b_2))


Особенности работы с временными зонами

Luxon хранит моменты времени как DateTime, которые уже включают информацию о временной зоне или фиксируются в UTC.

При пересечении интервалов важно учитывать:

  • пересечение происходит по абсолютной временной шкале
  • разные временные зоны не влияют на сам алгоритм пересечения
  • сравнение идёт через внутреннее представление времени, а не строковые значения

Пример:

const a = Interval.fromDateTimes(
  DateTime.fromISO("2026-05-01T10:00+03:00"),
  DateTime.fromISO("2026-05-01T12:00+03:00")
);

const b = Interval.fromDateTimes(
  DateTime.fromISO("2026-05-01T09:00Z"),
  DateTime.fromISO("2026-05-01T11:00Z")
);

Luxon автоматически приводит значения к единой временной шкале перед сравнением.


Поведение при граничных значениях

Особое внимание требуется при совпадении границ:

  • если A.end === B.start, пересечения нет
  • если интервалы имеют общую точку только на границе — результат null
  • если граница включена в одном и исключена в другом логически, Luxon всё равно использует полуоткрытую модель

Это важно для планирования задач, расписаний и бронирований, где такие случаи часто встречаются.


Связь с другими методами Interval

Метод intersection часто используется вместе с:

  • overlaps() — проверка наличия пересечения без вычисления интервала
  • union() (через объединение логики вручную) — построение общего диапазона
  • isBefore, isAfter — анализ расположения интервалов

Пример проверки перед пересечением:

if (a.overlaps(b)) {
  const result = a.intersection(b);
}

Типичные ошибки при использовании

1. Ожидание включённой правой границы

Распространённое заблуждение — считать интервалы закрытыми [start, end], что приводит к неожиданным null при касании границ.


2. Игнорирование null-результата

const result = a.intersection(b);
console.log(result.start); // ошибка, если result == null

Корректная обработка:

const result = a.intersection(b);
if (result) {
  console.log(result.start.toISO());
}

3. Предположение о симметричности входных данных

a.intersection(b) === b.intersection(a)

Метод действительно симметричен по результату, но не по внутреннему контексту использования, особенно если далее применяются цепочки операций над интервалами.


Практическое применение

Метод используется в задачах:

  • вычисление свободных временных окон
  • пересечение графиков событий
  • синхронизация расписаний
  • анализ занятости ресурсов
  • обработка временных фильтров в системах логирования

Пример нахождения общего времени доступности:

const common = meetingsA.intersection(meetingsB);
if (common) {
  // есть общий слот
}

Поведение при невалидных интервалах

Luxon предполагает, что:

  • start < end

Если интервал создан с нарушением этого условия, поведение методов, включая intersection, становится неопределённым или приводит к пустым результатам.


Композиция пересечений

Метод может применяться последовательно:

const result = a
  .intersection(b)
  ?.intersection(c);

Такая цепочка позволяет вычислять общую область пересечения множества интервалов, сводя задачу к последовательному сужению диапазона времени.