Квартальная система в Moment.js реализована как надстройка над календарной логикой месяцев и позволяет оперировать периодами по три месяца: первый квартал (январь–март), второй (апрель–июнь), третий (июль–сентябрь), четвертый (октябрь–декабрь). Работа с кварталами встроена в ядро библиотеки и не требует дополнительных плагинов.
Для получения номера квартала используется метод
quarter(). Он возвращает значение от 1 до 4 в зависимости
от текущей даты:
moment('2026-02-10').quarter(); // 1
moment('2026-05-10').quarter(); // 2
moment('2026-08-10').quarter(); // 3
moment('2026-11-10').quarter(); // 4
Логика вычисления основана на месяце даты, который делится на интервалы по три месяца с округлением вверх.
Метод quarter(value) позволяет задавать квартал вручную.
Допустимые значения — от 1 до 4. При изменении квартала Moment.js
автоматически пересчитывает месяц внутри соответствующего диапазона,
сохраняя день месяца, если это возможно.
moment('2026-01-15').quarter(3); // перевод в третий квартал → июль (или ближайший корректный день)
moment('2026-01-15').quarter(4); // перевод в четвертый квартал → октябрь
При выходе за пределы количества дней в целевом месяце происходит автоматическая нормализация даты.
Для работы с границами кварталов используется метод
startOf('quarter') и endOf('quarter').
moment('2026-05-10').startOf('quarter'); // 2026-04-01 00:00:00
moment('2026-05-10').endOf('quarter'); // 2026-06-30 23:59:59.999
Внутри реализации Moment.js выполняется приведение месяца к первому или последнему месяцу квартала, после чего дата корректируется до начала или конца соответствующего месяца.
Границы квартала всегда соответствуют локальному календарю, если не используется UTC-режим:
moment.utc('2026-05-10').startOf('quarter');
Для вывода квартала в строковом формате используется токен
Q в методе format().
moment('2026-05-10').format('Q'); // "2"
moment('2026-05-10').format('[Q]Q'); // "Q2"
Дополнительно применяется порядковый формат Qo,
учитывающий локализацию порядковых чисел:
moment('2026-05-10').format('Qo'); // "2nd" (в зависимости от локали)
Форматирование интегрируется с системой локалей Moment.js, где могут определяться собственные правила отображения порядковых суффиксов.
Методы add() и subtract() поддерживают
работу с кварталами через ключ quarter.
moment('2026-01-15').add(1, 'quarter'); // переход во 2 квартал
moment('2026-07-10').subtract(2, 'quarter'); // сдвиг на два квартала назад
При выполнении операций учитывается календарная структура: добавление одного квартала эквивалентно добавлению трёх месяцев, но с сохранением семантики квартального периода, а не фиксированного количества дней.
Внутренне операция сводится к преобразованию:
Метод diff() позволяет вычислять разницу между датами в
кварталах:
moment('2026-10-01').diff(moment('2026-01-01'), 'quarter'); // 3
moment('2026-07-01').diff(moment('2026-02-01'), 'quarter'); // 1
Расчёт выполняется через приведение дат к месячной шкале и последующее деление на три месяца с округлением вниз.
Точная логика зависит от временной точки: сравнение всегда опирается на начало квартала, если явно не указаны дополнительные параметры округления.
При переходах между кварталами Moment.js учитывает неодинаковую длину месяцев. Например:
moment('2026-01-31').quarter(2);
В апреле нет 31 числа, поэтому дата нормализуется до последнего допустимого дня месяца (30 апреля). Эта особенность критична при массовых вычислениях дат, привязанных к квартальным отчётам.
Квартальные операции часто комбинируются с другими уровнями времени:
moment('2026-05-10')
.startOf('quarter')
.add(10, 'days')
.format('YYYY-MM-DD');
Или:
moment('2026-05-10')
.endOf('quarter')
.subtract(1, 'month');
Каждый шаг пересчитывает внутреннее состояние объекта Moment, включая дату, время и таймзону.
Кварталы используются как базовый элемент для агрегирования данных:
const start = moment().quarter(1).startOf('quarter');
const end = moment().quarter(1).endOf('quarter');
Такая конструкция фиксирует границы периода независимо от текущего дня внутри квартала.
Кварталы в Moment.js основаны на григорианском календаре без учёта финансовых или нестандартных календарных систем. Финансовый год, начинающийся, например, в апреле, не поддерживается напрямую и требует ручной корректировки:
moment().month(3).startOf('month').quarter(1);
В таких случаях квартальная логика переопределяется через смещение начала года.
Квартал является производной единицей от месяцев, поэтому любые операции сводятся к месячной арифметике:
Недели не участвуют в расчёте квартала напрямую, но могут использоваться для дополнительной детализации внутри периода:
moment('2026-05-10')
.startOf('quarter')
.weeks();
При использовании moment.utc() квартальная логика
сохраняется, но все вычисления выполняются в UTC-календаре:
moment.utc('2026-05-10').quarter(); // 2
moment.utc('2026-05-10').startOf('quarter');
Различия между локальным и UTC-режимом проявляются только в смещениях дат, но не в границах квартала.
При установке квартала и выполнении арифметики учитываются следующие особенности:
Эти правила обеспечивают стабильность при массовых вычислениях временных диапазонов и построении отчётных систем, основанных на квартальной структуре времени.