Moment.js изначально не предоставляет встроенной поддержки праздников, однако библиотека обладает гибкими инструментами для работы с датами, что позволяет реализовать обработку праздников самостоятельно или интегрировать внешние источники данных о праздничных днях. В данной главе рассмотрены подходы к определению, проверке и управлению праздниками с использованием возможностей Moment.js.
Праздники можно хранить в виде массива объектов или строк, где каждая
запись соответствует конкретной дате. Для удобства используется формат
ISO 8601 (YYYY-MM-DD), который Moment.js обрабатывает без
дополнительных преобразований:
const holidays = [
"2026-01-01", // Новый год
"2026-05-01", // Праздник Весны и Труда
"2026-12-25" // Рождество
];
Для динамических праздников, например, Пасха, создаются функции вычисления даты в зависимости от года:
function calculateEaster(year) {
const f = Math.floor,
G = year % 19,
C = f(year / 100),
H = (C - f(C / 4) - f((8 * C + 13) / 25) + 19 * G + 15) % 30,
I = H - f(H / 28) * (1 - f(H / 28) * f(29 / (H + 1)) * f((21 - G) / 11)),
J = (year + f(year / 4) + I + 2 - C + f(C / 4)) % 7,
L = I - J,
month = 3 + f((L + 40) / 44),
day = L + 28 - 31 * f(month / 4);
return moment(`${year}-${month}-${day}`, "YYYY-M-D");
}
const easter2026 = calculateEaster(2026);
Для проверки, является ли определённая дата праздничной, создаётся функция, сравнивающая даты с массивом праздников:
function isHoliday(date, holidaysList) {
const formattedDate = moment(date).format("YYYY-MM-DD");
return holidaysList.includes(formattedDate);
}
const someDate = moment("2026-05-01");
console.log(isHoliday(someDate, holidays)); // true
В случае динамических праздников можно расширить функцию:
const dynamicHolidays = [
calculateEaster(2026).format("YYYY-MM-DD")
];
function isHolidayExtended(date) {
const formatted = moment(date).format("YYYY-MM-DD");
return holidays.includes(formatted) || dynamicHolidays.includes(formatted);
}
Для анализа календаря часто требуется получить все праздники за
определённый промежуток времени. Используется метод
moment.range (из библиотеки moment-range),
который позволяет итерировать даты в заданном диапазоне:
const { extendMoment } = require('moment-range');
const Moment = require('moment');
const moment = extendMoment(Moment);
const startDate = moment("2026-01-01");
const endDate = moment("2026-12-31");
const range = moment.range(startDate, endDate);
const holidaysInYear = Array.from(range.by('day')).filter(d => isHolidayExtended(d));
console.log(holidaysInYear.map(d => d.format("YYYY-MM-DD")));
Для расчётов с праздниками важно учитывать рабочие и выходные дни. В Moment.js нет встроенной логики для национальных календарей, но можно реализовать простую проверку:
function isWeekend(date) {
const day = moment(date).day(); // 0 — Воскресенье, 6 — Суббота
return day === 0 || day === 6;
}
function isWorkday(date) {
return !isWeekend(date) && !isHolidayExtended(date);
}
Использование функции позволяет фильтровать массив дат для составления рабочих графиков:
const workdaysInMay = Array.from(moment.range("2026-05-01", "2026-05-31").by('day'))
.filter(isWorkday)
.map(d => d.format("YYYY-MM-DD"));
Иногда требуется вводить региональные праздники или переносы праздничных дней на ближайший рабочий день. Можно реализовать функцию переноса:
function shiftHolidayIfWeekend(date) {
let m = moment(date);
if (m.day() === 6) m.add(2, 'days'); // перенос с субботы на понедельник
if (m.day() === 0) m.add(1, 'days'); // перенос с воскресенья на понедельник
return m;
}
const shiftedHolidays = holidays.map(shiftHolidayIfWeekend);
Таким образом обеспечивается корректное отображение праздников в рабочем календаре.
Для более сложных задач можно использовать API праздничных
календарей, которые возвращают даты в формате JSON. После получения
данных Moment.js позволяет преобразовать строки в объекты
moment и выполнять все перечисленные проверки и
фильтрации:
fetch("https://example.com/api/holidays?year=2026")
.then(res => res.json())
.then(data => {
const apiHolidays = data.map(d => moment(d.date));
const combinedHolidays = [...holidays, ...apiHolidays];
console.log(isHoliday("2026-12-25", combinedHolidays));
});
Moment.js предоставляет удобные методы для форматирования дат:
const holiday = moment("2026-01-01");
console.log(holiday.format("DD MMMM YYYY")); // 01 января 2026
console.log(holiday.format("dddd, MMMM Do YYYY")); // четверг, января 1-го 2026
Это позволяет создавать визуально понятные календарные отчёты и интегрировать даты в интерфейс приложений.
Комбинация возможностей Moment.js по работе с датами, массивами и диапазонами позволяет создавать гибкие системы для управления праздниками, определения рабочих и выходных дней, реализации переносов и интеграции внешних календарей. Использование стандартных методов форматирования обеспечивает удобное представление данных для дальнейшей обработки или отображения.