В работе с датами и временем в JavaScript важную роль играет интерпретация временных интервалов как дискретных единиц: сутки, неделя, месяц, квартал, год. В такой модели каждый интервал имеет не только начало, но и строго определённый конец, который зависит от выбранной единицы измерения.
В библиотеке Moment.js концепция конца периода реализуется через нормализацию объекта времени к последнему возможному моменту выбранной единицы измерения. Это позволяет оперировать датами в терминах календарных границ, а не абсолютных миллисекунд.
Конец периода — это момент времени, в который заканчивается выбранная единица измерения при календарной интерпретации.
Примеры:
Важно, что речь идёт не о добавлении фиксированного количества миллисекунд, а о вычислении последнего допустимого значения в рамках календарной системы.
Основной инструмент работы с концом периода — метод
endOf.
moment().endOf('day')
moment().endOf('month')
moment().endOf('year')
Каждый вызов изменяет объект времени, приводя его к последнему моменту указанной единицы.
При вызове:
moment('2026-05-10T12:34:56').endOf('day')
результат будет:
2026-05-10 23:59:59.999
При этом исходное время полностью перезаписывается в рамках той же календарной даты.
Конец периода зависит от уровня агрегирования:
Каждый уровень включает в себя более мелкие единицы, которые при
вызове endOf обнуляются или максимизируются.
Пример:
moment('2026-05-10 10:20:30').endOf('hour')
Результат:
2026-05-10 10:59:59.999
Конец месяца зависит от количества дней:
moment('2026-02-15').endOf('month')
Результат:
2026-02-28 23:59:59.999
или в високосный год:
2026-02-29 23:59:59.999
Неделя зависит от локали и настройки начала недели.
moment().endOf('week')
В одних конфигурациях конец недели может приходиться на субботу, в других — на воскресенье.
При вычислении конца периода учитывается текущая временная зона окружения.
Особенности:
Пример:
moment.utc('2026-05-10').endOf('day')
Результат:
2026-05-10T23:59:59.999Z
Метод endOf изменяет исходный объект времени.
const m = moment('2026-05-10 12:00:00');
m.endOf('day');
После выполнения m уже содержит конечное значение
дня.
Для сохранения исходного состояния используется клонирование:
const m1 = moment('2026-05-10 12:00:00');
const m2 = m1.clone().endOf('day');
Конец периода всегда парно связан с началом:
startOf('day') → 00:00:00.000endOf('day') → 23:59:59.999Это используется для построения диапазонов:
const start = moment('2026-05-10').startOf('day');
const end = moment('2026-05-10').endOf('day');
Такой диапазон охватывает весь календарный день.
Конец периода часто применяется в логике фильтрации:
const now = moment();
if (now.isBefore(moment().endOf('day'))) {
// текущий момент находится внутри сегодняшнего дня
}
Или при проверке попадания в интервал:
const target = moment('2026-05-10 18:00:00');
const start = moment('2026-05-10').startOf('day');
const end = moment('2026-05-10').endOf('day');
target.isBetween(start, end, null, '[]');
Квадратные скобки указывают на включение границ.
При переходах между единицами измерения возникают важные особенности:
moment('2026-05-10 12:00:00.123').endOf('second')
Результат:
2026-05-10 12:00:00.999
moment('2026-05-10 12:15:30').endOf('hour')
Результат:
2026-05-10 12:59:59.999
Кварталы вычисляются по фиксированному делению года:
moment('2026-05-10').endOf('quarter')
Результат:
2026-06-30 23:59:59.999
При вызове endOf происходит нормализация:
Пример:
moment('2026-01-15 10:10:10.500').endOf('day')
Результат:
2026-01-15 23:59:59.999
Временной конец периода не равен простому добавлению интервала:
moment().add(1, 'day')
и
moment().endOf('day')
имеют принципиально разные семантики:
add → смещение во времениendOf → переход к границе календарного интервалаЧастая проблема — неправильная интерпретация конца периода как исключающей границы.
Правильная логика:
endOf('day') включает весь деньНекоторые системы хранения времени обрезают миллисекунды, что приводит к:
Конец периода часто используется для построения сложных диапазонов:
const range = {
start: moment('2026-01-01').startOf('year'),
end: moment('2026-01-01').endOf('year')
};
Такие конструкции применяются в аналитике, отчетности и агрегации данных.
Метод endOf может быть частью цепочки:
moment('2026-05-10')
.add(2, 'days')
.endOf('day')
.format('YYYY-MM-DD HH:mm:ss')
Каждый шаг трансформирует состояние объекта, пока не достигается конечная календарная граница.