Создание Interval

В библиотеке Luxon интервал (Interval) представляет собой непрерывный промежуток времени между двумя моментами — началом и концом. В отличие от отдельных объектов DateTime, интервал описывает не точку, а диапазон, что делает его удобным для моделирования расписаний, бронирований, периодов активности и любых временных отрезков.

Ключевая особенность интервала заключается в строгой зависимости от двух границ:

  • start — начало интервала (DateTime)
  • end — конец интервала (DateTime)

Любой интервал в Luxon строится вокруг этих двух значений.


Базовое создание через fromDateTimes

Наиболее прямой способ создания интервала — использование метода Interval.fromDateTimes.

import { DateTime, Interval } from "luxon";

const start = DateTime.local(2026, 1, 1, 10, 0);
const end = DateTime.local(2026, 1, 1, 12, 0);

const interval = Interval.fromDateTimes(start, end);

В этом случае:

  • первый аргумент задаёт начало
  • второй аргумент задаёт конец
  • оба значения должны быть экземплярами DateTime

Если end меньше start, интервал считается некорректным:

const invalid = Interval.fromDateTimes(end, start);

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


Создание интервала из ISO-строк

Luxon поддерживает создание интервалов из строк формата ISO 8601 через Interval.fromISO.

const interval = Interval.fromISO("2026-01-01T10:00/2026-01-01T12:00");

Формат всегда включает две части, разделённые символом /:

start/end

Каждая часть может быть:

  • полным ISO-датой
  • датой без времени (в этом случае применяется локальное время по умолчанию)

Пример с датой:

const interval = Interval.fromISO("2026-01-01/2026-01-05");

В таком случае интервал охватывает период от начала первого дня до конца второго значения в рамках внутренней интерпретации Luxon.


Создание открытых интервалов: after и before

Luxon предоставляет способы создания полубесконечных интервалов, где известна только одна граница.

Интервал после момента

const start = DateTime.local(2026, 1, 1, 10, 0);

const interval = Interval.after(start, { hours: 3 });

В этом случае:

  • начало фиксировано
  • длительность задаётся через объект Duration-подобного формата
  • конец вычисляется автоматически

Интервал до момента

const end = DateTime.local(2026, 1, 1, 12, 0);

const interval = Interval.before(end, { hours: 2 });

Здесь:

  • конец фиксирован
  • начало вычисляется как end - duration

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


Нулевые и вырожденные интервалы

Если начало и конец совпадают:

const point = DateTime.local(2026, 1, 1, 10, 0);
const interval = Interval.fromDateTimes(point, point);

получается интервал нулевой длины. Он считается валидным, но его продолжительность равна нулю:

interval.length; // 0

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


Невалидные интервалы

Интервал может быть помечен как невалидный в нескольких случаях:

  • end < start
  • некорректные или отсутствующие DateTime
  • ошибки парсинга ISO-строк

Проверка осуществляется через свойство:

interval.isValid

Доступ к границам интервала

После создания интервала его границы доступны напрямую:

const start = interval.start;
const end = interval.end;

Обе границы являются объектами DateTime.

Важно учитывать, что изменение самих DateTime не мутирует интервал — он остаётся неизменяемым объектом. Любая трансформация создаёт новый интервал.


Создание интервалов на основе существующих данных

Часто интервалы формируются из уже вычисленных дат, например, из результатов API или бизнес-логики.

function createMeetingInterval(meeting) {
  return Interval.fromDateTimes(
    DateTime.fromISO(meeting.start),
    DateTime.fromISO(meeting.end)
  );
}

Такой подход позволяет централизованно контролировать корректность временных диапазонов.


Влияние временных зон на создание интервалов

Поскольку Interval опирается на DateTime, временная зона играет критическую роль. При создании интервала:

const start = DateTime.fromISO("2026-01-01T10:00", { zone: "Europe/Almaty" });
const end = DateTime.fromISO("2026-01-01T12:00", { zone: "Europe/Almaty" });

const interval = Interval.fromDateTimes(start, end);

оба значения интерпретируются в рамках одной зоны. Несогласованность зон может приводить к логическим ошибкам при сравнении интервалов.


Нормализация границ при создании

Luxon не пытается автоматически «исправить» порядок дат. Передача некорректного порядка:

Interval.fromDateTimes(later, earlier);

не приводит к перестановке значений, а формирует невалидный интервал. Поэтому нормализация должна выполняться явно:

const start = DateTime.min(a, b);
const end = DateTime.max(a, b);

const interval = Interval.fromDateTimes(start, end);

Использование длительности при косвенном создании

Хотя Interval не принимает Duration напрямую в fromDateTimes, длительность часто участвует в вычислении границ:

const start = DateTime.local(2026, 1, 1, 10);
const duration = { hours: 4 };

const end = start.plus(duration);

const interval = Interval.fromDateTimes(start, end);

Такой подход позволяет создавать интервалы фиксированной продолжительности от базового момента.


Создание интервалов из строк с частичной информацией

При использовании fromISO допускаются сокращённые формы:

Interval.fromISO("2026-01-01T10:00/12:00");

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


Пограничные случаи парсинга

Некоторые строки могут приводить к неожиданным результатам:

  • отсутствие временной зоны
  • неполные даты
  • смешение форматов даты и времени

Пример:

Interval.fromISO("2026-01-01T10:00/2026-01-01");

В таких случаях конечная точка интерпретируется как начало указанного дня.


Фабричные методы и их роль

Основные способы создания интервалов в Luxon сводятся к нескольким фабрикам:

  • Interval.fromDateTimes(start, end) — базовый способ
  • Interval.fromISO(string) — строковый парсинг
  • Interval.after(start, duration) — интервал вперёд
  • Interval.before(end, duration) — интервал назад
  • Interval.invalid(reason) — создание невалидного интервала

Каждый метод служит отдельному сценарию моделирования времени и позволяет избегать ручных вычислений границ.


Явное создание невалидного интервала

Иногда требуется представление отсутствующего или ошибочного временного диапазона:

const interval = Interval.invalid("Missing time range");

Такой интервал используется как маркер ошибки и не участвует в вычислениях.


Итоговая модель создания

Логика формирования интервала в Luxon сводится к единому принципу:

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