Начало и конец периода

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

Базовая модель работы строится вокруг объекта DateTime, который представляет конкретный момент времени с учётом часового пояса, локали и календарных правил. Период в этом контексте — это производная конструкция, формируемая через:

  • явное ограничение диапазона (Interval)
  • вычисление начала и конца единиц времени (startOf, endOf)

Начало периода: startOf

Метод startOf нормализует момент времени до начала указанной временной единицы. Он обнуляет более мелкие компоненты даты, сохраняя более крупные.

Сигнатура поведения

DateTime.startOf(unit: string): DateTime

Поддерживаемые единицы включают:

  • year
  • month
  • week
  • day
  • hour
  • minute
  • second
  • millisecond

Начало календарных единиц

Начало дня

const dt = DateTime.local(2026, 5, 23, 14, 45);
const start = dt.startOf('day');

Результат фиксирует время на 00:00:00.000 текущего дня.

Начало месяца

const startMonth = dt.startOf('month');

Обнуляется день, время и все меньшие единицы, устанавливая дату на первое число месяца.

Начало года

const startYear = dt.startOf('year');

Дата нормализуется к 1 января текущего года с нулевым временем.


Особенность работы с неделями

const startWeek = dt.startOf('week');

Неделя зависит от локали. В некоторых конфигурациях началом считается понедельник, в других — воскресенье. Luxon использует ICU-календарь, поэтому результат зависит от настроек локали окружения.


Конец периода: endOf

Метод endOf выполняет противоположную операцию: он расширяет момент времени до последнего возможного значения указанной единицы.

Сигнатура поведения

DateTime.endOf(unit: string): DateTime

Конец дня

const end = dt.endOf('day');

Результат устанавливает время на:

23:59:59.999

Конец месяца

const endMonth = dt.endOf('month');

Количество дней учитывается автоматически, включая високосные годы и различную длину месяцев.


Конец года

const endYear = dt.endOf('year');

Фиксируется 31 декабря 23:59:59.999 текущего года.


Взаимосвязь startOf и endOf

Обе операции симметричны и часто применяются совместно для построения диапазонов.

const start = dt.startOf('day');
const end = dt.endOf('day');

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


Интервалы и формализация периода через Interval

Luxon предоставляет отдельную структуру Interval, которая превращает пару дат в полноценный объект периода.

const interval = Interval.fromDateTimes(
  dt.startOf('day'),
  dt.endOf('day')
);

Interval поддерживает:

  • проверку пересечений
  • включение даты в диапазон
  • объединение интервалов
  • разбиение на части

Проверка попадания в период

interval.contains(DateTime.local());

Метод определяет, принадлежит ли момент времени заданному интервалу.


Пересечение интервалов

interval.overlaps(otherInterval);

Используется при работе с календарями, расписаниями и временными окнами.


Границы календарных единиц и точность

Каждая единица времени имеет фиксированную иерархию:

  • year → month → day → hour → minute → second → millisecond

При вызове startOf или endOf происходит каскадное обнуление или заполнение всех нижестоящих уровней.

Пример каскада для startOf(‘month’)

  • день → 1
  • час → 0
  • минута → 0
  • секунда → 0
  • миллисекунда → 0

Пример каскада для endOf(‘month’)

  • день → последний день месяца
  • час → 23
  • минута → 59
  • секунда → 59
  • миллисекунда → 999

Часовые пояса и влияние на границы периода

Luxon строго учитывает часовой пояс объекта DateTime. Это влияет на вычисление начала и конца периода, особенно при переходах между зонами.

const dt = DateTime.fromISO('2026-03-29T10:00:00', { zone: 'Europe/Berlin' });

При вызове:

dt.startOf('day');

результат будет зависеть от локального времени зоны, а не UTC.


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

При DST (Daylight Saving Time) некоторые дни могут:

  • иметь 23 часа
  • иметь 25 часов

Luxon корректно адаптирует startOf('day') и endOf('day'), избегая несуществующих локальных времён.


Работа с частичными единицами

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

Часовой период

dt.startOf('hour')
dt.endOf('hour')

Формирует интервал внутри одного часа с точностью до миллисекунд.


Минутный период

dt.startOf('minute')
dt.endOf('minute')

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


Использование в агрегации данных

Операции начала и конца периода часто применяются для группировки событий.

Пример логической группировки по дням

  • определить начало дня
  • определить конец дня
  • фильтровать события по интервалу
const start = dt.startOf('day');
const end = dt.endOf('day');

events.filter(e =>
  Interval.fromDateTimes(start, end).contains(e.time)
);

Граничные состояния и точность сравнения

Luxon работает с миллисекундной точностью. Это означает, что:

  • endOf('day') всегда заканчивается на 999 ms
  • любые сравнения включают или исключают границы в зависимости от логики интервала

Особое значение имеет включительность границ в Interval, где начало включается, а конец — нет.


Особенности вычислений при разных календарях

Luxon использует ICU-календарь, поэтому:

  • длина месяца определяется календарной системой
  • неделя зависит от локали
  • начало недели может варьироваться

Это напрямую влияет на результат startOf('week').


Комбинирование startOf и endOf в цепочках

Методы поддерживают цепочное использование через DateTime:

const result = DateTime.local()
  .startOf('month')
  .plus({ days: 10 })
  .endOf('day');

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


Нормализация временных диапазонов

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

  • начало периода — для нижней границы фильтра
  • конец периода — для верхней границы

Это обеспечивает стабильность при сравнении и хранении данных в базах, где временные диапазоны должны быть детерминированными и независимыми от формата ввода.