v2 requires PHP 8.4 or higher. Update your composer.json accordingly.
In v1, get() returned an associative array of name => date and getInRange() returned date => name:
// v1
$holidays = Holidays::for('be')->get();
// ['Nieuwjaar' => CarbonImmutable, ...]
$holidays = Holidays::for('be')->getInRange('2024-01-01', '2024-12-31');
// ['2024-01-01' => 'Nieuwjaar', ...]In v2, both methods return an array of Holiday objects:
// v2
$holidays = Holidays::for('be')->get();
$holidays[0]->name; // 'Nieuwjaar'
$holidays[0]->date; // CarbonImmutable('2024-01-01')
$holidays[0]->type; // HolidayType::National
json_encode($holidays[0]);
// {"name":"Nieuwjaar","date":"2024-01-01","type":"national","region":null}In v1, these methods accepted optional $country and $year parameters that silently created a new instance:
// v1
$h = Holidays::for('be', 2024);
$h->get('nl', 2025);
$h->isHoliday('2024-01-01', 'nl');
$h->getName('2024-01-01', 'nl');In v2, call Holidays::for() for each country/year combination:
// v2
Holidays::for('be', 2024)->get();
Holidays::for('nl', 2025)->get();
Holidays::for('nl')->isHoliday('2024-01-01');
Holidays::for('nl')->getName('2024-01-01');The Denmark country code has been corrected from da to dk to match the ISO 3166-1 alpha-2 standard:
// v1
Holidays::for('da')->get();
// v2
Holidays::for('dk')->get();In v1, all countries were limited to years 1970–2037. In v2, this global limit has been removed. Most countries now support any year. Countries that depend on precomputed calendar lookup tables (Islamic, Indian, etc.) declare their own range:
// v1: throws for ANY country outside 1970–2037
Holidays::for('be', year: 2050)->get(); // InvalidYear
// v2: most countries work for any year
Holidays::for('be', year: 2050)->get(); // works
// v2: calendar-dependent countries have their own range
Holidays::for('tr', year: 2050)->get();
// InvalidYear: Only years between 1970 and 2037 are supported for tr.These are internal changes that don't require any action on your part.
Holiday::national()andHoliday::religious()accept both strings andCarbonImmutable— dates can be passed as strings (e.g.,"{$year}-01-01") orCarbonImmutableinstances. ThecreateDate()helper in theCountrybase class provides type-safe date parsing with explicit error handling.- Translation system simplified — the
HasTranslationsinterface andTranslatabletrait have been removed. Translations are now built into theCountrybase class. ThedefaultLocale()method is nowprotected. - Translation file paths changed — translation files moved from
lang/{hyphenated-class-name}/tolang/{countryCode}/(e.g.lang/germany/becamelang/de/). Observabletrait renamed toHasObservedHolidays— its methods now only acceptCarbonInterfacedates instead of strings and$yearparameters.Islamicinterface tightened —islamicHolidays()return type changed fromarray<string, string|CarbonImmutable|CarbonPeriod>toarray<string, CarbonImmutable>.- Calendar lookup constants on countries like Albania, Turkey, and India are now
protected constinstead ofpublic const. supportedYearRange()— countries with calendar lookup tables now declare their supported year range explicitly.- Performance — country discovery now uses a static
CountryRegistrymap instead of filesystem scanning (glob()), and date parsing no longer runs regex/string-matching on every holiday. ResolvesCalendarDatestrait deduplicates shared date resolution logic across Islamic, Indian, Chinese, and Nepali calendar traits.HasRegionsinterface standardizes how countries declare and validate regional holiday support.Holidayvalue object andHolidayTypeenum provide structured, JSON-serializable return data instead of plain arrays.regionparameter onHolidays::for()allows passing a region code directly without constructing a country instance.- Islamic calendar methods are stricter —
arafat(),islamicNewYear(), andprophetMuhammadBirthday()now throwInvalidYearinstead of returningnullwhen a year is not found in the lookup table.