Токены для квартала

Квартал в Moment.js представляет собой производную календарную единицу времени, вычисляемую на основе месяца. В стандартной модели используется деление года на четыре части по три месяца:

  • I квартал: январь–март
  • II квартал: апрель–июнь
  • III квартал: июль–сентябрь
  • IV квартал: октябрь–декабрь

Moment.js реализует работу с кварталами через форматные токены и внутреннюю арифметику, основанную на номере месяца.


Основной токен для вывода номера квартала:

  • Q — квартал без форматирования (1–4)

Квартал вычисляется автоматически:

moment('2026-01-15').format('Q'); // "1"
moment('2026-05-10').format('Q'); // "2"
moment('2026-11-01').format('Q'); // "4"

Формула вычисления:

quarter = Math.floor(month / 3) + 1

где month — индекс месяца (0–11).


Использование квартала в строках форматирования

Токен Q применяется совместно с другими токенами даты:

moment('2026-07-20').format('YYYY [Q]Q');
// "2026 Q3"

Квадратные скобки используются для вывода буквального текста Q, чтобы избежать конфликтов с токеном.

Типичные комбинации:

moment().format('YYYY-[Q]Q');     // 2026-Q2
moment().format('Q квартал YYYY'); // 2 квартал 2026

Порядковый формат квартала (ordinal)

Для отображения квартала с порядковым суффиксом используется токен:

  • Qo — порядковый квартал (1st, 2nd, 3rd, 4th)

Поддержка зависит от локали, так как суффиксы формируются через механизмы i18n Moment.js.

moment('2026-02-10').format('Qo'); // "1st"
moment('2026-08-10').format('Qo'); // "3rd"

В разных локалях результат может отличаться:

moment.locale('ru');
moment('2026-02-10').format('Qo'); // "1-й" (в зависимости от локализации)

Логика вычисления квартала

Moment.js не хранит квартал как отдельное поле даты. Он вычисляется динамически из месяца:

  • январь (0) → Q1
  • февраль (1) → Q1
  • март (2) → Q1
  • апрель (3) → Q2

Эквивалент вычисления:

function getQuarter(date) {
  return Math.floor(date.month() / 3) + 1;
}

Парсинг квартала

Moment.js поддерживает разбор строки с кварталом через токен Q, но с ограничениями: квартал не определяет точную дату, поэтому используется первый месяц квартала.

moment('2026 3', 'YYYY Q').format();
// интерпретируется как начало третьего квартала

Результат:

// 2026-07-01T00:00:00

По умолчанию:

  • Q1 → январь
  • Q2 → апрель
  • Q3 → июль
  • Q4 → октябрь

Квартал в вычислении начала и конца периода

Кварталы часто используются для построения отчетных периодов:

const start = moment().quarter(2).startOf('quarter');
const end = moment().quarter(2).endOf('quarter');

Результат:

  • начало: 2026-04-01
  • конец: 2026-06-30 (или 06-30 23:59:59.999)

Метод quarter(n) устанавливает квартал, сохраняя год и корректируя месяц.


Работа с startOf и endOf

Moment.js поддерживает агрегирование по кварталам:

moment('2026-05-15').startOf('quarter');
moment('2026-05-15').endOf('quarter');

Логика:

  • startOf('quarter') → первый день первого месяца квартала
  • endOf('quarter') → последний момент последнего месяца квартала

Квартал и другие единицы времени

Квартал связан с месяцами и годом, но не с неделями:

Единица Связь
year содержит 4 квартала
quarter содержит 3 месяца
month базовая единица расчёта
week не влияет на квартал

Особенности локализации Qo

Токен Qo зависит от правил локали:

  • английский: 1st, 2nd, 3rd, 4th
  • русский: 1-й, 2-й, 3-й, 4-й
  • французский: 1er, 2e, 3e, 4e

Moment.js использует таблицы ordinal-суффиксов внутри локалей, поэтому результат может быть различным даже при одинаковом вводе.


Типичные ошибки при использовании кварталов

Ошибка 1: ожидание фиксированной даты квартала

Квартал не является датой, он вычисляется из месяца:

moment('2026 Q2', 'Q') // не полноценная дата

Ошибка 2: путаница с финансовыми кварталами

Финансовый год часто начинается не с января, например в апреле. Moment.js не поддерживает смещение квартала без кастомной логики:

function fiscalQuarter(date) {
  return Math.floor((date.month() - 3 + 12) % 12 / 3) + 1;
}

Кварталы в пользовательских форматах

Комбинации токенов позволяют строить отчётные строки:

moment().format('YYYY [Q]Q');
// 2026 Q2

moment().format('YYYY [Квартал] Q');
// 2026 Квартал 2

Преобразование месяца в квартал вручную

Иногда требуется независимая логика без Moment:

const month = 8; // сентябрь (0-based)
const quarter = Math.floor(month / 3) + 1; // 3

Moment.js эквивалент:

moment().quarter();

Использование в аналитических отчётах

Квартальные периоды часто применяются для агрегации данных:

const grouped = {};

data.forEach(item => {
  const q = moment(item.date).format('YYYY-[Q]Q');
  grouped[q] = (grouped[q] || 0) + item.value;
});

Результат группировки:

  • 2026-Q1
  • 2026-Q2
  • 2026-Q3
  • 2026-Q4