Группировка событий по датам

Moment.js — это мощная библиотека для работы с датами и временем в JavaScript. Она упрощает создание, парсинг, форматирование и манипулирование датами. Для группировки событий по датам ключевыми являются возможности Moment.js по сравнению и форматированию дат, а также работы с интервалами времени.

Создание объекта даты осуществляется через конструктор moment():

const now = moment();
const specificDate = moment('2026-05-22', 'YYYY-MM-DD');

Важно понимать, что объекты Moment.js всегда являются мутируемыми, то есть операции над ними изменяют исходный объект, если не использовать методы клонирования clone().

Форматирование и стандартные функции

Форматирование даты является базовой функцией для группировки, так как позволяет привести даты к единому виду:

const formatted = moment().format('YYYY-MM-DD'); // '2026-05-22'
const timeOnly = moment().format('HH:mm:ss');   // '14:35:12'

Форматирование позволяет выделять дни, недели, месяцы и годы, что облегчает последующую группировку.

Сравнение дат

Для группировки событий необходимо уметь сравнивать даты. Moment.js предоставляет методы:

  • isSame() — проверяет совпадение по определённой единице времени:
moment('2026-05-22').isSame('2026-05-22', 'day'); // true
moment('2026-05-22').isSame('2026-05-21', 'day'); // false
  • isBefore() и isAfter() — проверка последовательности событий:
moment('2026-05-21').isBefore('2026-05-22'); // true
moment('2026-05-23').isAfter('2026-05-22');  // true
  • diff() — вычисление разницы между датами в любой единице времени:
const start = moment('2026-05-20');
const end = moment('2026-05-22');
const diffDays = end.diff(start, 'days'); // 2

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

Группировка событий по дате

Для группировки массива событий по дате удобно использовать объект как словарь, где ключи — это отформатированные даты, а значения — массивы событий:

const events = [
  { name: 'Событие 1', date: '2026-05-22' },
  { name: 'Событие 2', date: '2026-05-22' },
  { name: 'Событие 3', date: '2026-05-23' }
];

const groupedEvents = {};

events.forEach(event => {
  const dateKey = moment(event.date).format('YYYY-MM-DD');
  if (!groupedEvents[dateKey]) {
    groupedEvents[dateKey] = [];
  }
  groupedEvents[dateKey].push(event);
});

Результат:

{
  '2026-05-22': [
    { name: 'Событие 1', date: '2026-05-22' },
    { name: 'Событие 2', date: '2026-05-22' }
  ],
  '2026-05-23': [
    { name: 'Событие 3', date: '2026-05-23' }
  ]
}

Группировка по неделям и месяцам

Помимо группировки по дням, часто требуется объединение событий по неделям или месяцам. Для этого удобно использовать методы startOf() и endOf():

const weekKey = moment(event.date).startOf('week').format('YYYY-[W]WW');
const monthKey = moment(event.date).format('YYYY-MM');
  • startOf('week') устанавливает дату на начало недели (по умолчанию воскресенье, можно изменить локаль).
  • Формат YYYY-[W]WW используется для обозначения недели в году.
  • YYYY-MM позволяет объединять события по месяцам.

Пример группировки по неделям:

const groupedByWeek = {};

events.forEach(event => {
  const weekKey = moment(event.date).startOf('week').format('YYYY-[W]WW');
  if (!groupedByWeek[weekKey]) groupedByWeek[weekKey] = [];
  groupedByWeek[weekKey].push(event);
});

Работа с временными интервалами

Moment.js совместим с библиотекой moment-range, которая упрощает работу с диапазонами дат. С её помощью можно проверять, попадает ли событие в конкретный период:

const { extendMoment } = require('moment-range');
const moment = extendMoment(require('moment'));

const range = moment.range('2026-05-20', '2026-05-25');
const eventDate = moment('2026-05-22');
const isInRange = range.contains(eventDate); // true

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

Сортировка событий перед группировкой

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

events.sort((a, b) => moment(a.date).diff(moment(b.date)));

Сортировка обеспечивает последовательность в группах и облегчает дальнейшую обработку.

Локализация и форматирование дат

Moment.js поддерживает локализацию, что важно для отображения дат в пользовательских интерфейсах:

moment.locale('ru');
moment('2026-05-22').format('LLLL'); // пятница, 22 мая 2026 г., 00:00

Локализация влияет на названия дней недели, месяцев и формат вывода времени.

Рекомендации по производительности

  • Для больших массивов событий лучше создавать объект-словарь вместо многократных фильтров.
  • Использовать клонирование при необходимости сохранения исходной даты (moment(event.date).clone()).
  • При группировке по неделям или месяцам форматировать ключ один раз, а не каждый раз вычислять заново сложные выражения.

Глубокое понимание этих методов Moment.js позволяет эффективно организовывать события по времени, формировать отчёты и создавать интерактивные календари, обеспечивая точное и удобное управление датами.