Работа с датой и временем в Luxon опирается на неизменяемые объекты
DateTime и Duration, что делает операции
округления и обрезания предсказуемыми и безопасными. Любая трансформация
возвращает новый объект, не изменяя исходный, поэтому все операции можно
выстраивать в цепочки без риска побочных эффектов.
Обрезание — это приведение времени к началу или концу выбранного интервала. В Luxon для этого используются методы, которые «сбрасывают» менее значимые компоненты даты.
Метод startOf(unit) устанавливает дату в начало
указанного интервала:
year — начало года (1 января, 00:00:00.000)month — начало месяцаweek — начало недели (зависит от локали)day — начало дня (00:00:00.000)hour, minute, secondПример логики обрезания:
import { DateTime } from "luxon";
const dt = DateTime.local(2026, 5, 23, 14, 37, 52, 123);
const startOfDay = dt.startOf("day");
const startOfHour = dt.startOf("hour");
const startOfMonth = dt.startOf("month");
Каждый вызов удаляет «хвост» менее значимых единиц времени. Например,
при startOf("hour") минуты, секунды и миллисекунды
обнуляются.
Ключевая особенность: startOf работает детерминированно
и всегда приводит значение к строго нижней границе интервала.
Метод endOf(unit) выполняет обратную операцию —
устанавливает дату в последнюю возможную точку интервала:
23:59:59.999const endOfDay = dt.endOf("day");
const endOfMonth = dt.endOf("month");
endOf часто используется при фильтрации диапазонов,
когда нужно включить весь интервал целиком.
Для более точечного контроля применяется метод set,
позволяющий явно задавать компоненты даты:
const truncated = dt.set({
second: 0,
millisecond: 0
});
Это не специализированное округление, а именно прямое присваивание значений.
Такой подход используется, когда необходимо:
Luxon позволяет работать с Unix-временем через
toMillis() и fromMillis(). Это удобно для
«жёсткого» обрезания через математические операции.
const ms = dt.toMillis();
const truncated = DateTime.fromMillis(ms - (ms % 1000));
Здесь происходит обрезание до секунд за счёт остатка от деления.
Аналогично можно обрезать до минут:
const truncatedToMinute =
DateTime.fromMillis(ms - (ms % 60000));
Такой способ применяется, когда требуется строгая числовая точность без использования API Luxon для компонентов.
Luxon не предоставляет универсального метода «round()» для
DateTime, поэтому округление реализуется комбинацией
операций извлечения времени и математических функций.
const ms = dt.toMillis();
const rounded = DateTime.fromMillis(
Math.round(ms / 60000) * 60000
);
Логика:
const roundedHour = DateTime.fromMillis(
Math.round(ms / 3600000) * 3600000
);
const roundedSecond = DateTime.fromMillis(
Math.round(ms / 1000) * 1000
);
Метод diff возвращает объект Duration,
который часто используется для вычисления разницы между датами:
const diff = dt1.diff(dt2, ["hours", "minutes"]);
Полученный Duration можно преобразовать в числовые
значения:
const hours = diff.as("hours");
const roundedHours = Math.round(hours);
Здесь округление происходит уже на уровне чисел, а не даты.
При работе с длительностями Luxon использует объект
Duration, который может содержать «переполненные» значения
(например, 90 минут вместо 1 часа 30 минут).
Метод:
duration.normalize();
приводит длительность к каноническому виду, перераспределяя значения по единицам времени.
Это не классическое округление, но важный шаг перед преобразованиями и форматированием.
Метод shiftTo позволяет преобразовать Duration в
заданный набор единиц:
const d = diff.shiftTo("hours", "minutes", "seconds");
После этого значения можно округлять выборочно:
const hours = Math.round(d.hours);
const minutes = Math.round(d.minutes);
Такой подход полезен при отображении пользовательских таймеров и отчётов.
При работе с дробными значениями (например, результат
as("seconds") может быть дробным) часто требуется
принудительное усечение:
const seconds = Math.floor(diff.as("seconds"));
или округление:
const seconds = Math.round(diff.as("seconds"));
Это базовый способ устранения погрешностей вычислений времени.
В реальных сценариях часто используется комбинация подходов:
const normalized = dt
.startOf("minute")
.plus({ minutes: Math.round(dt.second / 60) });
const base = dt.startOf("day");
const offset = Math.round(dt.diff(base, "minutes").minutes);
const result = base.plus({ minutes: offset });
При выводе значений через toFormat можно контролировать
отображение точности, но само округление выполняется заранее:
const formatted = dt
.set({ millisecond: 0 })
.toFormat("HH:mm:ss");
Важно различать:
При вычислениях между датами часто возникают дробные значения из-за миллисекунд:
const diff = dt1.diff(dt2, "seconds").seconds;
Такие значения почти всегда требуют округления:
Math.floor — для отсечения будущего времениMath.ceil — для гарантированного включения
интервалаMath.round — для симметричного округленияВыбор метода зависит от логики бизнес-задачи.
При смене временной зоны:
const shifted = dt.setZone("UTC");
значение времени не изменяется, но его представление в локальной зоне
может повлиять на результаты startOf и endOf.
Поэтому обрезание рекомендуется выполнять после приведения к нужной
временной зоне.
Все операции округления и обрезания в Luxon обладают ключевыми свойствами:
DateЭто позволяет безопасно комбинировать несколько уровней трансформаций времени без риска накопления ошибок или смещения состояния.