В библиотеке Luxon отсутствует метод с названием
divideEqually. В стандартном API нет функции, которая
напрямую делит временной интервал на равные части с возвратом набора
равномерно распределённых значений. При этом в Luxon присутствуют
инструменты, позволяющие реализовать подобное поведение вручную через
работу с Duration, DateTime и арифметикой
временных значений.
В Luxon существует метод Duration#divide, который
выполняет деление длительности на числовой коэффициент:
const { Duration } = require("luxon");
const d = Duration.fromObject({ hours: 10 });
const half = d.divide(2);
Результатом будет новая длительность, уменьшенная в два раза. Однако это не означает разбиение интервала на набор равных частей — метод возвращает только одну уменьшенную длительность.
Метод divideEqually в API отсутствует, поскольку
библиотека не предоставляет встроенного механизма генерации массива
интервалов или точек разбиения.
Равномерное деление временного промежутка обычно означает получение набора точек между началом и концом интервала, включая или исключая границы.
Базовая идея строится на переводе интервала в миллисекунды:
const { DateTime } = require("luxon");
const start = DateTime.fromISO("2026-01-01T00:00:00");
const end = DateTime.fromISO("2026-01-02T00:00:00");
const totalMillis = end.toMillis() - start.toMillis();
const parts = 4;
const step = totalMillis / parts;
Далее каждая точка вычисляется добавлением шага:
const points = Array.from({ length: parts + 1 }, (_, i) =>
DateTime.fromMillis(start.toMillis() + step * i)
);
В результате получается набор временных меток, равномерно распределённых по интервалу.
Если требуется получить именно интервалы, а не точки, используется смещение начальной границы:
const intervals = [];
for (let i = 0; i < parts; i++) {
const segmentStart = DateTime.fromMillis(start.toMillis() + step * i);
const segmentEnd = DateTime.fromMillis(start.toMillis() + step * (i + 1));
intervals.push({
start: segmentStart,
end: segmentEnd
});
}
Каждый элемент массива представляет собой независимый временной отрезок фиксированной длины.
При использовании DateTime важно учитывать, что
арифметика через toMillis() переводит время в абсолютную
шкалу UTC. Это устраняет проблемы с переходами часовых поясов и DST, но
приводит к тому, что результат всегда выражен в абсолютных
миллисекундах.
Альтернативный подход — использовать методы plus и
diff:
const stepDuration = end.diff(start).as("milliseconds") / parts;
const points = [];
for (let i = 0; i <= parts; i++) {
points.push(start.plus({ milliseconds: stepDuration * i }));
}
Этот вариант сохраняет семантику Luxon и лучше читается при работе в доменной логике времени.
При делении длительностей почти всегда возникает дробное значение миллисекунд. Это приводит к потенциальному накоплению ошибки при большом количестве сегментов.
Для устранения дрейфа последняя точка часто вычисляется напрямую:
const points = [];
for (let i = 0; i < parts; i++) {
points.push(start.plus({ milliseconds: stepDuration * i }));
}
points.push(end);
Так гарантируется, что конечная граница совпадает с исходным значением без погрешностей округления.
Если исходные данные представлены как Duration,
разбиение можно выполнять через преобразование в миллисекунды:
const { Duration } = require("luxon");
const duration = Duration.fromObject({ minutes: 90 });
const parts = 3;
const step = duration.as("milliseconds") / parts;
const split = Array.from({ length: parts }, () =>
Duration.fromMillis(step)
);
Однако такой подход теряет привязку к конкретным моментам времени и работает только с абстрактной длительностью.
Отсутствие divideEqually объясняется архитектурным
разделением ответственности:
DateTime отвечает за точки во времениDuration отвечает за длины интерваловРазбиение на равные части относится к прикладной логике, а не к
базовой модели времени, поэтому реализуется на уровне пользовательского
кода через комбинацию арифметики DateTime и
Duration.