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

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

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

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

dayjs.extend(quarterOfYear)

После подключения становится доступен метод quarter(), а также корректная работа с единицей времени quarter в startOf и endOf.

Дополнительно часто используется плагин advancedFormat, если требуется форматирование с использованием токена Q:

import advancedFormat from 'dayjs/plugin/advancedFormat'

dayjs.extend(advancedFormat)

Получение квартала

Квартал определяется числом от 1 до 4, вычисляемым на основе месяца даты.

dayjs('2026-01-15').quarter() // 1
dayjs('2026-05-10').quarter() // 2
dayjs('2026-09-01').quarter() // 3
dayjs('2026-12-31').quarter() // 4

Логика разбиения стандартная:

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

Метод работает как геттер и сеттер.

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

Метод quarter() может изменять текущий квартал даты:

dayjs('2026-01-15').quarter(3).format()
// 2026-07-15...

При установке квартала сохраняются день и время внутри допустимого диапазона нового периода. Если исходная дата находится, например, в конце месяца, который отсутствует в новом квартале (например, 31 число), Day.js автоматически нормализует значение.

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

После подключения quarterOfYear единица quarter становится доступной в методах startOf и endOf.

dayjs('2026-05-10').startOf('quarter')
// 2026-04-01 00:00:00

dayjs('2026-05-10').endOf('quarter')
// 2026-06-30 23:59:59.999

Эти методы используются для построения диапазонов дат, фильтрации и агрегации данных.

Типичная задача — вычисление периода отчетности:

const start = dayjs().startOf('quarter')
const end = dayjs().endOf('quarter')

Арифметика кварталов

Хотя Day.js не добавляет отдельный метод addQuarter, кварталы поддерживаются через общую систему единиц времени:

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

dayjs('2026-10-01').subtract(2, 'quarter')
// 2026-04-01

Квартал интерпретируется как три месяца, поэтому операции эквивалентны смещению по календарю с учетом длины месяцев.

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

Для отображения номера квартала в строковом формате используется токен Q, который активируется плагином advancedFormat:

dayjs('2026-05-10').format('Q')
// "2"

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

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

Сравнение кварталов

Кварталы удобно использовать для сравнения периодов через метод isSame с единицей quarter:

dayjs('2026-05-10').isSame('2026-06-01', 'quarter')
// true

dayjs('2026-05-10').isSame('2026-09-01', 'quarter')
// false

Также возможны проверки границ:

dayjs('2026-05-10').isAfter(dayjs('2026-04-01').startOf('quarter'))
dayjs('2026-05-10').isBefore(dayjs('2026-06-30').endOf('quarter'))

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

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

const data = [
  { date: '2026-01-10' },
  { date: '2026-03-22' },
  { date: '2026-07-05' }
]

const grouped = data.reduce((acc, item) => {
  const q = dayjs(item.date).quarter()
  const y = dayjs(item.date).year()
  const key = `${y}-Q${q}`

  if (!acc[key]) acc[key] = []
  acc[key].push(item)

  return acc
}, {})

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

Особенности работы и ограничения

Квартальная логика в Day.js зависит от локального календаря, но не учитывает финансовые или нестандартные начала года (например, fiscal year с июля). Для таких сценариев требуется дополнительная логика поверх базового API.

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

Методы startOf('quarter') и endOf('quarter') всегда приводят дату к строгим границам периода, что делает их надежной основой для построения диапазонов в запросах к API, базам данных и системам отчетности.