kosmosafive / production-calendar
Производственный календарь
Package info
github.com/kosmosafive/production-calendar
pkg:composer/kosmosafive/production-calendar
Requires
- php: ^8.4
- ext-dom: *
- ext-json: *
- psr/http-client: ^1.0
- psr/http-factory: ^1.1
- psr/simple-cache: ^3.0
- symfony/css-selector: ^7.0 || ^8.0
- symfony/dom-crawler: ^7.0 || ^8.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.95
- lendable/composer-license-checker: ^1.4
- mockery/mockery: ^1.6
- pestphp/pest: ^4.7
- phpstan/phpstan: ^2.1
- rector/rector: ^2.4
- roave/security-advisories: dev-latest
- shipmonk/composer-dependency-analyser: ^1.8
- symfony/var-dumper: ^8.0
Suggests
- guzzlehttp/guzzle: Для использования XmlCalendarProvider (или любой другой PSR-18 клиент)
- guzzlehttp/psr7: Для реализации PSR-17 RequestFactory
- symfony/cache: Для использования CachedHolidayProvider (реализация PSR-16)
This package is auto-updated.
Last update: 2026-05-29 12:36:01 UTC
README
Гибкий инструмент для работы с производственным календарем. Позволяет рассчитывать рабочие дни, учитывать государственные праздники и переносы, используя данные из API или локальных файлов.
Особенности
- Поддержка PSR-17/18 (любой HTTP-клиент: Guzzle, Symfony и т.д.).
- Поддержка PSR-16 для кеширования данных.
- Гибкая система провайдеров (API, локальный JSON, замыкания).
- Расчет интервалов и добавление рабочих дней.
- Итераторы для эффективной обработки периодов без загрузки всех данных в память.
- Поддержка нескольких стран через ISO-код (например,
by,ru).
Установка
composer require kosmosafive/production-calendar
Быстрый старт
use Kosmosafive\ProductionCalendar\ProductionCalendar; use Kosmosafive\ProductionCalendar\Provider\XmlCalendarProvider; use Kosmosafive\ProductionCalendar\Provider\CachedProvider; // 1. Настройка провайдера (с использованием вашего HTTP-клиента) $apiProvider = new XmlCalendarProvider($httpClient, $requestFactory); // 2. Добавляем кеширование (любой PSR-16 драйвер) $provider = new CachedProvider($apiProvider, $cache); // 3. Инициализация календаря $calendar = new ProductionCalendar($provider, 'ru'); // Проверка дня $calendar->isWorkday(new DateTime('2026-01-01')); // false (Новый год) // Расчет количества рабочих дней $workdaysCount = $calendar->countWorkdays( new DateTime('2026-05-01'), new DateTime('2026-05-31') ); // Прибавление 10 рабочих дней $deadline = $calendar->addWorkdays(new DateTime('now'), 10);
API календаря
Основные методы
isWorkday(DateTimeInterface $date): bool
Проверяет, является ли дата рабочим днем. Учитывает праздники, переносы и выходные.
countWorkdays(DateTimeInterface $start, DateTimeInterface $end): int
Подсчитывает количество рабочих дней в указанном диапазоне (включая границы).
addWorkdays(DateTimeInterface $date, int $days): DateTimeImmutable
Прибавляет указанное количество рабочих дней к дате. Отрицательное значение позволяет вычитать дни.
subtractWorkdays(DateTimeInterface $date, int $days): DateTimeImmutable
Вычитает указанное количество рабочих дней из даты (алиас для addWorkdays с отрицательным значением).
getClosestWorkday(DateTimeInterface $date, bool $forward = true): DateTimeImmutable
Находит ближайший рабочий день. Параметр $forward определяет направление поиска: вперед (true) или назад (false).
Итераторы
getWorkdaysIterator(DateTimeInterface $start, DateTimeInterface $end): Generator<DateTimeImmutable>
Возвращает генератор рабочих дней в диапазоне. Экономит память при обработке больших периодов.
getFullCalendarIterator(DateTimeInterface $start, DateTimeInterface $end): Generator<CalendarDay>
Возвращает полную информацию о каждом дне периода, включая тип дня, название праздника и информацию о переносах.
hasHolidays(DateTimeInterface $start, DateTimeInterface $end): bool
Проверяет наличие праздничных дней в указанном диапазоне.
Продвинутая конфигурация
Composite Provider (Приоритеты)
Вы можете использовать CompositeProvider, чтобы сначала проверять локальные исключения, а затем обращаться к API:
use Kosmosafive\ProductionCalendar\Provider\CompositeProvider; use Kosmosafive\ProductionCalendar\Provider\JsonProvider; $composite = new CompositeProvider( new JsonProvider(__DIR__ . '/config/holidays'), // Сначала ищем тут new XmlCalendarProvider($client, $factory) // Если файла нет, идем в API );
Closure Provider (Кастомная логика)
Для особых случаев можно использовать ClosureProvider:
use Kosmosafive\ProductionCalendar\Provider\ClosureProvider; $closureProvider = new ClosureProvider(function (string $country, int $year) { // Ваша логика получения данных return [ '2026-01-01' => new Day(new DateTimeImmutable('2026-01-01'), Type::Holiday, 'New Year'), ]; });
Структура JSON файла (для локального провайдера)
Файлы должны называться по шаблону {country}_{year}.json (например, ru_2026.json)
и соответствовать формату xmlcalendar.ru:
{
"months": [
{
"month": 1,
"days": "1,2,3,4,5,6,7,8,9+,10,11,17,18,24,25,31"
}
],
"transitions": [
{"from": "01.03", "to": "01.09"}
]
}
Выходные дни не обязательно добавлять в конфигурацию.
Специальные символы в конце дня месяца:
- символ
+(например,9+) означает перенос рабочего дня - символ
*(например,31*) означает сокращенный рабочий день
Типы дней
Библиотека использует следующие типы дней:
| Тип | Описание |
|---|---|
Type::Working |
Обычный рабочий день |
Type::Weekend |
Выходной день (суббота/воскресенье) |
Type::Holiday |
Праздничный день |
Type::PreHoliday |
Предпраздничный (сокращенный) день |
Type::Transferred |
Перенесенный рабочий день |
Примеры использования
Расчет срока выполнения задачи
$startDate = new DateTime('2026-01-15'); $workDaysNeeded = 20; $deadline = $calendar->addWorkdays($startDate, $workDaysNeeded); echo "Дедлайн: " . $deadline->format('Y-m-d');
Поиск последнего рабочего дня месяца
$lastDayOfMonth = new DateTime('2026-01-31'); $lastWorkday = $calendar->getClosestWorkday($lastDayOfMonth, forward: false); echo "Последний рабочий день: " . $lastWorkday->format('Y-m-d');
Анализ квартала
$start = new DateTime('2026-01-01'); $end = new DateTime('2026-03-31'); $workDaysCount = $calendar->countWorkdays($start, $end); $hasHolidays = $calendar->hasHolidays($start, $end); echo "Рабочих дней в Q1: $workDaysCount\n"; echo "Есть праздники: " . ($hasHolidays ? 'да' : 'нет') . "\n";
Требования
- PHP 8.4+
- PSR-17 (HTTP Factory) — для XML API провайдера
- PSR-18 (HTTP Client) — для XML API провайдера
- PSR-16 (Cache) — опционально, для кеширования
Лицензия
MIT License. См. файл LICENSE для подробностей.