Квартальное форматирование

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

Подключение поддержки кварталов

Функциональность кварталов включается через плагин quarterOfYear.

import dayjs from 'dayjs'
import quarterOfYear from 'dayjs/plugin/quarterOfYear'

dayjs.extend(quarterOfYear)

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


Определение квартала

Квартал определяется числом от 1 до 4, где:

  • 1 квартал: январь — март
  • 2 квартал: апрель — июнь
  • 3 квартал: июль — сентябрь
  • 4 квартал: октябрь — декабрь

Получение квартала текущей даты:

dayjs().quarter()

Получение квартала конкретной даты:

dayjs('2026-05-10').quarter() // 2
dayjs('2026-11-10').quarter() // 4

Установка квартала

Метод quarter() работает не только как геттер, но и как сеттер.

dayjs().quarter(3)

При установке квартала Day.js автоматически изменяет месяц и сохраняет относительную позицию дня внутри квартала, если это возможно.

Пример:

dayjs('2026-02-15').quarter(4).format('YYYY-MM-DD')

Дата будет перенесена в четвёртый квартал того же года с сохранением логики смещения внутри диапазона месяцев.


Форматирование кварталов

Day.js поддерживает форматирование квартала через токены:

  • Q — номер квартала (1–4)
  • Qo — порядковый формат (1st, 2nd, 3rd, 4th — зависит от локализации)

Примеры:

dayjs('2026-01-10').format('Q')  // "1"
dayjs('2026-07-10').format('Q')  // "3"

Формат с порядковым суффиксом:

dayjs('2026-04-10').format('Qo') // "2nd"

Форматирование может комбинироваться с другими токенами:

dayjs('2026-05-15').format('YYYY [Q]Q') // "2026 Q2"

Начало и конец квартала

Для аналитических задач часто требуется вычислить границы квартала.

Day.js предоставляет методы startOf и endOf:

dayjs('2026-05-15').startOf('quarter')

Результат — начало второго квартала:

2026-04-01 00:00:00

Конец квартала:

dayjs('2026-05-15').endOf('quarter')

Результат:

2026-06-30 23:59:59.999

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


Использование кварталов в аналитике

Кварталы часто применяются для агрегации данных: финансовые отчёты, пользовательская активность, планирование релизов.

Группировка по кварталу:

const dates = [
  '2026-01-10',
  '2026-02-15',
  '2026-05-20',
  '2026-08-01'
]

const grouped = dates.reduce((acc, date) => {
  const q = dayjs(date).format('YYYY-[Q]Q')

  if (!acc[q]) acc[q] = []
  acc[q].push(date)

  return acc
}, {})

Результат:

{
  "2026-Q1": ["2026-01-10", "2026-02-15"],
  "2026-Q2": ["2026-05-20"],
  "2026-Q3": ["2026-08-01"]
}

Кварталы и арифметика дат

Day.js позволяет выполнять арифметику с кварталами через метод add и subtract.

dayjs('2026-01-01').add(1, 'quarter')

Результат — переход на следующий квартал:

2026-04-01

Обратное смещение:

dayjs('2026-10-15').subtract(2, 'quarter')

Результат:

2026-04-15

При этом сохраняется логика календарных переходов, включая корректировку месяцев и дней.


Влияние високосных годов и длины месяцев

Квартальная логика опирается на календарные месяцы, поэтому:

  • первый квартал может содержать 90 или 91 день
  • второй квартал может содержать 91 день
  • февраль влияет на длину первого квартала в високосные годы

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


Работа с UTC и кварталами

При использовании utc плагина квартальная логика сохраняется, но операции выполняются в UTC-таймзоне.

import utc from 'dayjs/plugin/utc'

dayjs.extend(utc)
dayjs.extend(quarterOfYear)

dayjs.utc('2026-05-10').quarter()

Это важно для серверных расчётов, где требуется единая временная зона без локальных смещений.


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

Форматирование кварталов может быть встроено в сложные шаблоны отчетов.

dayjs('2026-09-12').format('[Отчёт за] YYYY, Q[Q]')

Результат:

Отчёт за 2026, 3Q

Также возможно комбинирование с месяцами и неделями:

dayjs('2026-07-05').format('YYYY-MM [Q]Q - WW [week]')

Фискальные кварталы

В некоторых системах календарный квартал не совпадает с финансовым. Day.js не содержит встроенной поддержки фискальных периодов, но логика может быть реализована через смещение дат.

Пример фискального года, начинающегося в апреле:

function fiscalQuarter(date) {
  const month = dayjs(date).month() // 0-11

  const shifted = (month - 3 + 12) % 12
  return Math.floor(shifted / 3) + 1
}

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


Особенности поведения при граничных датах

При переходах между кварталами важно учитывать:

  • конец марта → начало апреля
  • конец июня → начало июля
  • конец сентября → начало октября
  • конец декабря → начало января следующего года
dayjs('2026-03-31').add(1, 'day').format('YYYY-MM-DD')

Результат:

2026-04-01

Квартальная структура при этом автоматически пересчитывается.


Совместное использование с другими плагинами

Кварталы часто применяются вместе с:

  • relativeTime для отображения периода
  • isBetween для проверки попадания даты в диапазон
  • timezone для работы с локализациями
  • utc для серверной синхронизации

Пример проверки попадания даты в квартал:

const start = dayjs('2026-04-01')
const end = dayjs('2026-06-30')

dayjs('2026-05-10').isBetween(start, end, null, '[]')

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