Метод splitAt

Метод splitAt в библиотеке Luxon применяется к объектам Interval и предназначен для разбиения временного интервала на несколько меньших интервалов по заданным точкам разреза. Он используется для сегментации временных диапазонов, когда требуется получить последовательность непрерывных частей, ограниченных конкретными моментами времени.

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

interval.splitAt(...DateTime[] | DateTime[]): Interval[]

Метод принимает произвольное количество объектов DateTime или один массив DateTime. Каждый переданный момент времени рассматривается как точка разреза исходного интервала.

Результатом работы является массив объектов Interval.


Базовое поведение

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

Основные принципы работы:

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

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


Простейший пример

import { DateTime, Interval } from "luxon";

const start = DateTime.fromISO("2026-01-01T00:00:00");
const end = DateTime.fromISO("2026-01-01T12:00:00");

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

const split = interval.splitAt(
  DateTime.fromISO("2026-01-01T04:00:00"),
  DateTime.fromISO("2026-01-01T08:00:00")
);

split.forEach(i => {
  console.log(i.toISO());
});

Результат будет содержать три интервала:

  1. 00:00 → 04:00
  2. 04:00 → 08:00
  3. 08:00 → 12:00

Сортировка точек разреза

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

interval.splitAt(
  DateTime.fromISO("2026-01-01T10:00:00"),
  DateTime.fromISO("2026-01-01T02:00:00"),
  DateTime.fromISO("2026-01-01T06:00:00")
);

Фактический порядок разбиения будет: 02:00 → 06:00 → 10:00.


Игнорирование внешних точек

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

const interval = Interval.fromDateTimes(
  DateTime.fromISO("2026-01-01T05:00:00"),
  DateTime.fromISO("2026-01-01T10:00:00")
);

const result = interval.splitAt(
  DateTime.fromISO("2026-01-01T01:00:00"),
  DateTime.fromISO("2026-01-01T07:00:00"),
  DateTime.fromISO("2026-01-01T12:00:00")
);

В этом случае учитывается только 07:00, остальные точки игнорируются.


Поведение без точек разреза

Если метод вызывается без аргументов:

const result = interval.splitAt();

возвращается массив из одного элемента — исходного интервала:

[ interval ]

Пересечение с границами интервала

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

  • точка равная началу интервала фактически не создаёт отдельного сегмента слева;
  • точка равная концу интервала не создаёт сегмента справа;
  • если обе точки совпадают с границами, структура результата не меняется.

Несколько точек в одной позиции

Если несколько точек разреза совпадают по времени, они не приводят к созданию дублирующих сегментов. Интервал разрезается один раз в этой точке.


Работа с дробными интервалами

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

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

Пример с рабочим днём

const workDay = Interval.fromDateTimes(
  DateTime.fromISO("2026-01-01T09:00:00"),
  DateTime.fromISO("2026-01-01T18:00:00")
);

const breaks = workDay.splitAt(
  DateTime.fromISO("2026-01-01T12:00:00"),
  DateTime.fromISO("2026-01-01T15:00:00")
);

Результат:

  • 09:00 → 12:00
  • 12:00 → 15:00
  • 15:00 → 18:00

Отличие от splitBy

Метод splitAt не следует фиксированному шагу и работает исключительно с явными точками разреза. В отличие от него, splitBy (если используется в связке с интервалами в сторонних реализациях или утилитах) ориентирован на равномерное деление по длительности.

Ключевые различия:

  • splitAt — разбиение по конкретным моментам времени;
  • splitBy — разбиение по регулярному интервалу (например, каждые 30 минут).

Характеристика результата

Результирующий массив интервалов обладает следующими свойствами:

  • каждый элемент — валидный Interval;
  • интервалы идут в хронологическом порядке;
  • объединение всех сегментов полностью покрывает исходный интервал;
  • отсутствуют пересечения между сегментами;
  • длина массива зависит от количества валидных точек разреза.

Особенности использования с цепочками операций

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

const segments = interval
  .splitAt(t1, t2, t3)
  .map(i => i.toDuration().as("hours"));

Такой подход позволяет:

  • вычислять длительности отдельных сегментов;
  • применять фильтрацию по длине;
  • агрегировать интервалы по условиям.

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

Так как Interval опирается на DateTime, разрезание учитывает временные зоны объектов. При смешении DateTime с разными зонами происходит нормализация к единому внутреннему представлению, после чего выполняется разбиение.

Это означает:

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

Типовые сценарии применения

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

Поведение при крайних значениях

При некорректных или невалидных значениях DateTime (например, Invalid DateTime) такие точки игнорируются. Это предотвращает разрушение результата, но может приводить к неожиданно неделённому интервалу.


Итоговая модель работы

Логика метода сводится к следующей последовательности:

  1. извлечение всех точек разреза;
  2. фильтрация точек, не входящих в интервал;
  3. сортировка оставшихся точек;
  4. последовательное разбиение исходного интервала;
  5. формирование массива новых Interval.