Праздничные и выходные дни

Во многих веб-приложениях требуется учитывать праздничные и выходные дни при выборе даты. Такая логика используется в системах бронирования, доставке товаров, записи на приём, кадровых системах, финансовых сервисах и корпоративных календарях. Библиотека Flatpickr предоставляет набор инструментов для визуального выделения таких дней, ограничения выбора и реализации сложных календарных правил.

Основными задачами являются:

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

Выделение выходных дней через CSS

По умолчанию Flatpickr отображает все дни месяца одинаково. Для визуального выделения субботы и воскресенья можно использовать CSS-классы, которые библиотека автоматически назначает дням недели.

Пример оформления выходных:

.flatpickr-day:nth-child(7n),
.flatpickr-day:nth-child(7n-1) {
    color: #d32f2f;
    font-weight: bold;
}

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

Более надёжным считается использование событий Flatpickr.


Определение выходных через onDayCreate

Событие onDayCreate вызывается для каждой создаваемой ячейки календаря.

flatpickr("#date", {
    onDayCreate: function(dObj, dStr, fp, dayElem) {
        const day = dayElem.dateObj.getDay();

        if (day === 0 || day === 6) {
            dayElem.classList.add("weekend");
        }
    }
});

CSS:

.weekend {
    background-color: #fff3e0;
    color: #ef6c00;
}

Метод позволяет полностью контролировать внешний вид календаря.


Блокировка выходных дней

Во многих системах услуги предоставляются только в рабочие дни.

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

flatpickr("#date", {
    disable: [
        function(date) {
            return (
                date.getDay() === 0 ||
                date.getDay() === 6
            );
        }
    ]
});

Логика функции:

  • возвращает true — дата отключается;
  • возвращает false — дата остаётся доступной.

После применения настройки пользователь не сможет выбрать выходной день.


Создание списка праздничных дат

Чаще всего праздники представлены фиксированным набором дат.

const holidays = [
    "2026-01-01",
    "2026-01-02",
    "2026-03-08",
    "2026-05-01",
    "2026-12-25"
];

Использование:

flatpickr("#date", {
    disable: holidays
});

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


Комбинирование праздников и выходных

На практике требуется учитывать оба типа нерабочих дней одновременно.

const holidays = [
    "2026-01-01",
    "2026-03-08",
    "2026-05-01"
];

flatpickr("#date", {
    disable: [
        ...holidays,
        function(date) {
            return date.getDay() === 0 ||
                   date.getDay() === 6;
        }
    ]
});

Flatpickr корректно объединяет разные правила блокировки.


Подсветка праздничных дат без блокировки

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

const holidays = [
    "2026-01-01",
    "2026-03-08",
    "2026-05-01"
];

flatpickr("#date", {
    onDayCreate: function(dObj, dStr, fp, dayElem) {
        const currentDate =
            fp.formatDate(dayElem.dateObj, "Y-m-d");

        if (holidays.includes(currentDate)) {
            dayElem.classList.add("holiday");
        }
    }
});

CSS:

.holiday {
    background: #ffebee;
    color: #c62828;
    border-radius: 50%;
}

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


Отображение названий праздников

Полезно показывать название праздника при наведении курсора.

const holidays = {
    "2026-01-01": "Новый год",
    "2026-03-08": "Международный женский день",
    "2026-05-01": "Праздник труда"
};

flatpickr("#date", {
    onDayCreate: function(dObj, dStr, fp, dayElem) {

        const date =
            fp.formatDate(dayElem.dateObj, "Y-m-d");

        if (holidays[date]) {
            dayElem.title = holidays[date];
            dayElem.classList.add("holiday");
        }
    }
});

При наведении пользователь увидит название события через стандартный tooltip браузера.


Использование data-атрибутов

Дополнительная информация о праздниках может храниться в атрибутах элемента.

if (holidays[date]) {
    dayElem.dataset.holiday =
        holidays[date];
}

Пример:

<span
  data-holiday="Новый год">
</span>

Эти данные удобно использовать для собственных всплывающих подсказок.


Выделение длинных праздничных периодов

Некоторые праздники продолжаются несколько дней подряд.

Например, новогодние каникулы:

flatpickr("#date", {
    disable: [
        {
            from: "2026-01-01",
            to: "2026-01-10"
        }
    ]
});

Все даты диапазона становятся недоступными.


Генерация праздничного диапазона программно

Большие периоды удобнее формировать автоматически.

function generateDates(start, end) {

    const result = [];

    let current = new Date(start);

    while (current <= end) {

        result.push(
            current.toISOString()
                .split("T")[0]
        );

        current.setDate(
            current.getDate() + 1
        );
    }

    return result;
}

const holidays =
    generateDates(
        new Date("2026-01-01"),
        new Date("2026-01-10")
    );

Полученный массив можно использовать в параметре disable.


Работа с плавающими праздниками

Не все праздники имеют фиксированную дату.

Например:

  • Пасха;
  • Курбан айт;
  • День благодарения;
  • некоторые национальные праздники.

Для них дата вычисляется программно.

const holidays = [
    calculateHoliday(2026)
];

После вычисления список передаётся в Flatpickr как обычный массив дат.


Получение праздничных дней с сервера

Во многих проектах праздничный календарь хранится на сервере.

fetch("/api/holidays")
    .then(response => response.json())
    .then(holidays => {

        flatpickr("#date", {
            disable: holidays
        });

    });

Преимущества:

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

Асинхронное обновление календаря

Если праздники изменились после инициализации календаря, настройки можно обновить.

instance.set(
    "disable",
    holidays
);

Либо полностью перестроить календарь:

instance.redraw();

Разделение праздничных дней по странам

Международные системы часто поддерживают несколько государств.

const holidayMap = {

    kz: [
        "2026-03-22",
        "2026-12-16"
    ],

    ru: [
        "2026-01-01",
        "2026-05-09"
    ],

    us: [
        "2026-07-04",
        "2026-11-26"
    ]
};

Использование:

const country = "kz";

flatpickr("#date", {
    disable: holidayMap[country]
});

Переключение календаря по выбранной стране

При изменении страны можно динамически менять набор праздников.

countrySelect.addEventListener(
    "change",
    event => {

        const country =
            event.target.value;

        calendar.set(
            "disable",
            holidayMap[country]
        );
    }
);

Такой механизм часто встречается в международных HR-системах.


Совмещение праздников с минимальной датой

Нередко требуется разрешить выбор только будущих рабочих дней.

flatpickr("#date", {
    minDate: "today",

    disable: [
        function(date) {

            return (
                date.getDay() === 0 ||
                date.getDay() === 6
            );

        }
    ]
});

В результате:

  • прошлые даты недоступны;
  • выходные недоступны;
  • рабочие дни доступны.

Проверка праздничного дня после выбора

Даже если праздник не заблокирован, может потребоваться дополнительная обработка.

flatpickr("#date", {

    onChange: function(
        selectedDates
    ) {

        const date =
            selectedDates[0]
                .toISOString()
                .split("T")[0];

        if (holidays.includes(date)) {

            console.log(
                "Выбран праздничный день"
            );
        }
    }
});

Подобная проверка полезна для отображения предупреждений или изменения бизнес-логики.


Отображение специальных маркеров

Вместо изменения цвета можно добавлять значки.

onDayCreate:
function(dObj, dStr, fp, dayElem) {

    const date =
        fp.formatDate(
            dayElem.dateObj,
            "Y-m-d"
        );

    if (holidays.includes(date)) {

        dayElem.innerHTML +=
            "<span class='marker'>★</span>";
    }
}

CSS:

.marker {
    display: block;
    font-size: 10px;
    text-align: center;
}

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


Создание производственного календаря

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

  • рабочие дни;
  • выходные;
  • праздничные дни;
  • сокращённые дни;
  • переносы выходных.

Структура данных может выглядеть следующим образом:

const calendar = {
    holidays: [
        "2026-01-01",
        "2026-03-08"
    ],

    weekends: [0, 6],

    shortDays: [
        "2026-12-31"
    ]
};

Затем каждая категория визуально оформляется через onDayCreate.


Использование enable вместо disable

Иногда проще определить только рабочие дни.

flatpickr("#date", {
    enable: [
        function(date) {

            return (
                date.getDay() >= 1 &&
                date.getDay() <= 5
            );
        }
    ]
});

Теперь выбрать можно исключительно будние дни.


Производительность при большом количестве праздников

Если список содержит сотни или тысячи дат, поиск через includes() может стать менее эффективным.

Оптимизация:

const holidaySet =
    new Set(holidays);

Проверка:

holidaySet.has(date);

Преимущества:

  • постоянное время поиска;
  • снижение нагрузки при построении календаря;
  • более быстрая работа обработчика onDayCreate.

Архитектура хранения праздничных данных

Для крупных проектов распространён следующий подход:

{
    holidays: [],
    weekends: [],
    shortDays: [],
    transfers: [],
    workingWeekends: []
}

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