Interval.splitBy делит интервал на последовательность подинтервалов одинаковой длительности и возвращает массив объектов Interval, покрывающих исходный диапазон времени без пропусков и пересечений.
Основой работы метода является разбиение временного промежутка на шаги фиксированной длины, заданной через Duration-like значение. Каждый следующий элемент начинается ровно в момент окончания предыдущего, а последний подинтервал при необходимости подгоняется под границу исходного интервала.
Метод вызывается у объекта Interval:
interval.splitBy(duration: DurationLike): Interval[]
duration может задаваться в формате, который
поддерживает Luxon:
Ключевое требование: длительность должна быть положительной и ненулевой, иначе поведение становится некорректным или приводит к исключению.
Пусть задан интервал:
И задан шаг разбиения Δt.
Алгоритм формирует последовательность:
до тех пор, пока конец очередного сегмента не достигнет или не превысит B.
Если B не кратен Δt относительно A, последний интервал обрезается:
Таким образом гарантируется точное покрытие исходного интервала.
Разбиение происходит строго по временной шкале Luxon, без попыток «выравнивания» под календарные единицы.
Важные свойства:
При переходах через DST (летнее/зимнее время) фактическая длительность последнего или промежуточных интервалов в миллисекундах может отличаться от ожидаемой календарной, если используется нефиксированная длительность (например, «1 day»).
import { DateTime, Interval, Duration } from "luxon";
const start = DateTime.fromISO("2026-01-01T00:00:00");
const end = DateTime.fromISO("2026-01-01T10:00:00");
const interval = Interval.fromDateTimes(start, end);
const parts = interval.splitBy({ hours: 2 });
Результат:
Если длина интервала не кратна шагу:
const start = DateTime.fromISO("2026-01-01T00:00:00");
const end = DateTime.fromISO("2026-01-01T09:30:00");
const interval = Interval.fromDateTimes(start, end);
const parts = interval.splitBy({ hours: 2 });
Результат будет:
Последний сегмент автоматически подстраивается под конечную границу исходного интервала.
Luxon различает:
При splitBy это различие критично:
interval.splitBy({ minutes: 30 })
Каждый шаг равен строго 30 минутам в миллисекундах.
interval.splitBy({ days: 1 })
Зависит от календаря и временной зоны. В дни с переходом времени сутки могут иметь не 24 часа.
Передача:
{ hours: 0 }{ minutes: -10 }приводит к некорректному разбиению. В нормальных сценариях такие значения исключаются до вызова метода, поскольку алгоритм разбиения требует строго положительного шага.
Так как Interval оперирует DateTime, каждый подинтервал сохраняет исходную временную зону:
const start = DateTime.fromISO("2026-03-30T00:00:00", { zone: "Europe/Berlin" });
const end = start.plus({ hours: 6 });
const interval = Interval.fromDateTimes(start, end);
const parts = interval.splitBy({ hours: 1 });
При переходе на летнее время возможны ситуации, когда фактические «часы» смещаются, но границы интервалов остаются корректными по абсолютному времени.
Вместо ручного построения:
let cursor = start;
const result = [];
while (cursor < end) {
const next = cursor.plus({ hours: 1 });
result.push(Interval.fromDateTimes(cursor, next > end ? end : next));
cursor = next;
}
splitBy инкапсулирует:
Метод применяется в сценариях, где требуется регулярная сегментация временного диапазона:
Результат всегда представляет собой массив Interval, где:
Эта структура делает результат пригодным для дальнейшей цепочной обработки без дополнительной нормализации данных.