luedtke / laravel-holiday-facade
Public holiday lookups for Laravel with multi-country driver support, Bundesland filtering, observance/strict mode and translation in five languages.
Requires
- php: ^8.2
- ext-calendar: *
- illuminate/support: ^13.0
Requires (Dev)
- orchestra/testbench: ^9.0|^10.0|^11.0
- pestphp/pest: ^3.0|^4.0
- pestphp/pest-plugin-laravel: ^3.0|^4.0
README
A Laravel package for working with public holidays across multiple countries. Provides a clean facade API with multi-language support, region/state filtering, strict mode, and fully customisable holidays via config.
Requirements
- PHP ^8.2
- Laravel ^13.0
Installation
composer require luedtke/laravel-holiday-facade
The service provider is auto-discovered. Publish the config file:
php artisan vendor:publish --tag=holiday-config
Optionally publish the translation files if you want to customise holiday names:
php artisan vendor:publish --tag=holiday-lang
Configuration
// config/holiday.php return [ 'default' => 'germany', // active driver 'default_locale' => env('HOLIDAY_LOCALE', 'en'), // fallback translation locale 'drivers' => [ 'germany' => [ 'driver' => 'germany', 'timezone' => env('HOLIDAY_TIMEZONE_DE', 'Europe/Berlin'), 'locale' => 'de_DE', 'default_state' => env('HOLIDAY_DEFAULT_STATE_DE', null), // e.g. 'BY' ], 'swedish' => [ 'driver' => 'swedish', 'timezone' => env('HOLIDAY_TIMEZONE_SE', 'Europe/Stockholm'), 'locale' => 'sv_SE', ], 'finnish' => [ 'driver' => 'finnish', 'timezone' => env('HOLIDAY_TIMEZONE_FI', 'Europe/Helsinki'), 'locale' => 'fi_FI', ], 'netherlands' => [ 'driver' => 'netherlands', 'timezone' => env('HOLIDAY_TIMEZONE_NL', 'Europe/Amsterdam'), 'locale' => 'nl_NL', ], ], 'custom' => [ // Repeats every year (MM-DD) ['name' => 'Company Day', 'date' => '06-15', 'type' => 'custom'], // One-time date ['name' => 'Office Closed', 'date' => '2026-12-27', 'type' => 'custom'], ], ];
Basic Usage
use Laravel\Holiday\Facades\Holiday; // Is a date a public holiday? Holiday::isHoliday('2026-12-25'); // true Holiday::isHoliday('2026-12-24'); // false — Christmas Eve is an observance Holiday::isHoliday('2026-12-24', strict: false); // true — includes observances // Is a date a workday? Holiday::isWorkday('2026-12-25'); // false Holiday::isWorkday('2026-12-24'); // true — observances are workdays by default // Next / previous holiday Holiday::next('2026-12-20')->name; // "1. Weihnachtstag" Holiday::previous('2026-01-10')->name; // "Neujahr" // Next workday Holiday::nextWorkday('2026-12-24'); // Carbon instance for 2026-12-28 // Get all holidays for a year Holiday::getHolidays(2026); // Collection of Holiday objects // Get holidays in a date range Holiday::getHolidaysBetween('2026-04-01', '2026-04-30'); // Count holidays Holiday::countHolidays(2026); // int // Look up a holiday by date Holiday::getHoliday('2026-12-25'); // Holiday value object // Check by name Holiday::isHolidayByName('Neujahr', 2026); // true
Switching Drivers
Use the driver() method to switch country at runtime:
Holiday::driver('swedish')->isHoliday('2026-06-19'); // true — Midsommarafton (observance) Holiday::driver('finnish')->getHolidays(2026); Holiday::driver('netherlands')->next('2026-04-20')->name; // "Koningsdag"
Supported Countries
| Driver | Country | Regional holidays |
|---|---|---|
germany |
Germany | Yes — 16 Bundesländer |
swedish |
Sweden | No |
finnish |
Finland | No |
netherlands |
Netherlands | No |
State / Region Filtering (Germany)
Germany has regional public holidays that apply only to specific Bundesländer. Pass a state code to filter:
// Only holidays that apply to Bavaria (BY) Holiday::getHolidays(2026, state: 'BY'); // Heilige Drei Könige applies to BY, BW, ST — not to HH Holiday::isHolidayByName('Heilige Drei Könige', state: 'BY'); // true Holiday::isHolidayByName('Heilige Drei Könige', state: 'HH'); // false // Get the list of supported state codes Holiday::supportedRegions(); // ['BW', 'BY', 'BE', ...]
Set a permanent default state via config or .env so you never have to pass it explicitly:
HOLIDAY_DEFAULT_STATE_DE=BY
Strict Mode
By default, HolidayType::Observance days (e.g. Christmas Eve, Midsummer Eve, New Year's Eve) are excluded from semantic checks like isHoliday() and next() because they are not statutory days off.
Pass strict: false to include them:
Holiday::isHoliday('2026-12-24'); // false — strict by default Holiday::isHoliday('2026-12-24', strict: false); // true Holiday::next('2026-12-23'); // 2026-12-25 (skips Christmas Eve) Holiday::next('2026-12-23', strict: false); // 2026-12-24 (includes Christmas Eve) Holiday::countHolidays(2026); // excludes observances Holiday::countHolidays(2026, strict: false); // includes observances
Default $strict per method:
true (excludes observances) |
false (includes observances) |
|---|---|
isHoliday, isWorkday, nextWorkday |
getHolidays, getHolidaysBetween |
next, previous, countHolidays |
getHoliday, isHolidayByName |
Translations
Every holiday has a stable translation key. Call translate() on any Holiday value object to get the name in a different language:
$holiday = Holiday::next('2026-12-24'); $holiday->name; // "1. Weihnachtstag" (native — always German for the germany driver) $holiday->translate('en'); // "Christmas Day" $holiday->translate('de'); // "1. Weihnachtstag" $holiday->translate('sv'); // "Juldagen" $holiday->translate(); // uses app()->getLocale(), falls back to config('holiday.default_locale')
Supported locales: de, en, fi, nl, sv
Set the default translation locale in your .env:
HOLIDAY_LOCALE=en
Override individual translation files after publishing:
php artisan vendor:publish --tag=holiday-lang
# edit resources/lang/vendor/holiday/en/holidays.php
Custom Holidays
Add company-specific or one-time holidays to config/holiday.custom. They are automatically merged into every driver result.
'custom' => [ // Repeats every year — format: MM-DD ['name' => 'Company Day', 'date' => '06-15', 'type' => 'custom'], // One-time date — format: YYYY-MM-DD ['name' => 'Office Closed', 'date' => '2026-12-27', 'type' => 'custom'], // Region-restricted custom holiday ['name' => 'Munich Office Day', 'date' => '09-21', 'type' => 'custom', 'states' => ['BY']], ],
Supported types: public, observance, custom
Holiday Value Object
Every method returns (or works with) a Holiday value object:
$holiday = Holiday::getHoliday('2026-12-25'); $holiday->name; // "1. Weihnachtstag" $holiday->date; // Carbon instance $holiday->country; // "germany" $holiday->type; // HolidayType::Public $holiday->states; // null (nationwide) or ['BY', 'BW', ...] $holiday->locale; // "de_DE" $holiday->key; // "christmas_day" (stable translation key) $holiday->translate('en'); // "Christmas Day"
Testing
composer test
License
This package is open-sourced software licensed under the MIT license.