spatie/holidays
Composer 安装命令:
composer require spatie/holidays
包简介
Calculate public holidays
README 文档
README
This package can calculate public holidays for a country.
use Spatie\Holidays\Holidays; $holidays = Holidays::for('be')->get(); $holidays[0]->name; // 'Nieuwjaar' $holidays[0]->date; // CarbonImmutable('2024-01-01') $holidays[0]->type; // HolidayType::National
Support us
We invest a lot of resources into creating best in class open source packages. You can support us by buying one of our paid products.
We highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using. You'll find our address on our contact page. We publish all received postcards on our virtual postcard wall.
Installation
You can install the package via composer:
composer require spatie/holidays
This package requires PHP 8.4+.
Supported countries
We support the countries listed in this directory. If you want to add a country, please create a pull request. See Adding a new country for a guide.
Usage
You can get all holidays for a country by using the get method. It returns an array of Holiday objects.
use Spatie\Holidays\Holidays; $holidays = Holidays::for('be')->get(); foreach ($holidays as $holiday) { $holiday->name; // 'Nieuwjaar' $holiday->date; // CarbonImmutable instance $holiday->type; // HolidayType::National }
You can pass a country instance or an ISO 3166-1 alpha-2 code:
use Spatie\Holidays\Countries\Belgium; $holidays = Holidays::for(Belgium::make())->get(); $holidays = Holidays::for('be')->get();
The Holiday object implements JsonSerializable:
json_encode($holidays[0]); // {"name":"Nieuwjaar","date":"2024-01-01","type":"national","region":null}
Getting holidays for a specific year
$holidays = Holidays::for(country: 'be', year: 2024)->get();
Getting holidays between two dates
The getInRange method returns all holidays between two dates (inclusive). Dates are swappable — the lower date is always used as the start.
$holidays = Holidays::for('be')->getInRange('2024-01-01', '2024-12-31');
You can also use shorthand formats:
$holidays = Holidays::for('be')->getInRange('2024', '2025'); // full years $holidays = Holidays::for('be')->getInRange('2024-06', '2025-05'); // year-month
Getting holidays in a specific language
$holidays = Holidays::for(country: 'be', locale: 'fr')->get();
If no translation file exists for the given locale, the original holiday names are returned.
Regional holidays
Some countries have region-specific holidays. You can pass a region code to the for method:
$holidays = Holidays::for('de', year: 2024, region: 'DE-BW')->get();
Or use the country class directly:
use Spatie\Holidays\Countries\Germany; $holidays = Holidays::for(Germany::make('DE-BW'), year: 2024)->get();
To discover which regions a country supports:
use Spatie\Holidays\Countries\Germany; Germany::regions(); // ['DE-BW', 'DE-BY', 'DE-BE', ...]
Countries that support regions: Australia, Bosnia and Herzegovina, Brazil, France, Germany, Malaysia, Spain, Switzerland.
Determining if a date is a holiday
Holidays::for('be')->isHoliday('2024-01-01'); // true
Determining if today is a holiday
Holidays::for('be')->isTodayHoliday(); // true or false
Getting upcoming holidays
$holidays = Holidays::for('be')->getUpcoming(3); // Returns the next 3 upcoming holidays foreach ($holidays as $holiday) { echo $holiday->date; // CarbonImmutable echo $holiday->name; }
Getting long weekends
$longWeekends = Holidays::for('de', 2024)->getLongWeekends(); // With custom minimum days (default: 4) $longWeekends = Holidays::for('de', 2024)->getLongWeekends(3); foreach ($longWeekends as $weekend) { echo $weekend->startDate; // First day of the long weekend echo $weekend->endDate; // Last day of the long weekend echo $weekend->dayCount; // Number of days echo $weekend->holidays; // Array of Holiday objects }
Getting the name of a holiday
Holidays::for('be')->getName('2024-01-01'); // 'Nieuwjaar'
Determining whether a country is supported
Holidays::has('be'); // true Holidays::has('unknown'); // false
Adding a new country
This is a community driven package. If you find any errors, please create a pull request with the fix, or at least open an issue.
Basic country
Create a new class in src/Countries that extends Country. At minimum, you need to implement countryCode() and allHolidays():
use Spatie\Holidays\Countries\Country; use Spatie\Holidays\Holiday; use Spatie\Holidays\HolidayType; class MyCountry extends Country { public function countryCode(): string { return 'xx'; // ISO 3166-1 alpha-2 code } protected function allHolidays(int $year): array { return [ Holiday::national("New Year's Day", "{$year}-01-01"), Holiday::national('Christmas', "{$year}-12-25"), ]; } }
The Holiday::national() helper accepts both strings and CarbonImmutable instances. For Easter-based holidays, use the easter() or orthodoxEaster() helpers:
protected function allHolidays(int $year): array { $easter = $this->easter($year); return [ Holiday::national('Good Friday', $easter->subDays(2)), Holiday::national('Easter Monday', $easter->addDay()), ]; }
For relative dates, use CarbonImmutable::parse():
Holiday::national('Labor Day', CarbonImmutable::parse("first monday of September {$year}"));
If your country defines holidays in a non-English language, override defaultLocale():
protected function defaultLocale(): string { return 'de'; }
Register your country
In src/CountryRegistry.php, add your ISO country code and country class to the MAP constant.
Regional holidays
If your country has region-specific holidays, implement the HasRegions interface:
use Spatie\Holidays\Contracts\HasRegions; use Spatie\Holidays\Exceptions\InvalidRegion; class MyCountry extends Country implements HasRegions { protected function __construct(protected ?string $region = null) { if ($region !== null && ! in_array($region, static::regions())) { throw InvalidRegion::notFound($region); } } public static function regions(): array { return ['XX-A', 'XX-B', 'XX-C']; } public function region(): ?string { return $this->region; } protected function allHolidays(int $year): array { return array_merge( $this->nationalHolidays($year), $this->regionHolidays($year), ); } protected function regionHolidays(int $year): array { return match ($this->region) { 'XX-A' => ['Regional Day' => CarbonImmutable::createFromDate($year, 6, 1)], default => [], }; } }
Observed holidays
If your country moves holidays that fall on a weekend to the next weekday, use the HasObservedHolidays trait:
use Spatie\Holidays\Concerns\HasObservedHolidays; use Spatie\Holidays\Holiday; class MyCountry extends Country { use HasObservedHolidays; protected function allHolidays(int $year): array { $holidays = [ Holiday::national("New Year's Day", "{$year}-01-01"), ]; // Example: if New Year's Day falls on a weekend, add an observed day $newYear = $this->sundayToNextMonday($holidays[0]->date); if ($newYear !== null) { $holidays[] = Holiday::observed("New Year's Day (Observed)", $newYear); } return $holidays; } }
The trait provides these methods (each returns null if no shift applies):
weekendToNextMonday(CarbonInterface $date)— shifts Saturday/Sunday to MondaysundayToNextMonday(CarbonInterface $date)— shifts Sunday to MondayobservedChristmasDay(CarbonInterface $date)— Saturday to Monday, Sunday to TuesdayobservedBoxingDay(CarbonInterface $date)— Saturday to Monday, Sunday to Tuesday
Holiday types
The Holiday class supports different holiday types:
use Spatie\Holidays\Holiday; use Spatie\Holidays\HolidayType; Holiday::national('New Year', "{$year}-01-01"); // Default type Holiday::regional('Regional Day', "{$year}-06-01", 'XX-RE'); // With region Holiday::religious('Easter', $easterDate); // Religious holidays Holiday::observed('Observed Day', $observedDate); // Observed holidays Holiday::banked('Bank Holiday', "{$year}-12-25"); // Bank holidays
Available types in HolidayType enum: National, Regional, Religious, Observed, Banked.
Calendar systems
For countries that use Islamic, Chinese, Indian, or Nepali calendar dates, use the corresponding calendar trait. These traits rely on precomputed lookup tables defined as protected const arrays on your country class:
use Spatie\Holidays\Calendars\IslamicCalendar; use Spatie\Holidays\Contracts\Islamic; class MyCountry extends Country implements Islamic { use IslamicCalendar; protected const eidAlFitr = [ 2024 => '04-10', 2025 => '03-30', // ... ]; protected const eidAlAdha = [ 2024 => '06-16', 2025 => '06-06', // ... ]; }
Countries with lookup tables must declare their supported year range:
protected function supportedYearRange(): array { return [2024, 2037]; // [min, max] based on your lookup data }
For multi-day holidays (like Eid), use convertPeriods() to expand a CarbonPeriod into individual named days:
$this->convertPeriods('Eid al-Fitr', $year, $this->eidAlFitr($year)[0], includeEve: true);
Available calendar traits: IslamicCalendar, ChineseCalendar, IndianCalendar, NepaliCalendar.
Translations
To add translations for a country, create a JSON file at lang/{countryCode}/{locale}/holidays.json:
{
"New Year's Day": "Jour de l'An",
"Christmas": "Noël"
}
The keys must match the holiday names returned by allHolidays().
Testing
- Create a test file in
tests/Countries/:
use Carbon\CarbonImmutable; use Spatie\Holidays\Holidays; it('can calculate my country holidays', function () { CarbonImmutable::setTestNow('2024-01-01'); $holidays = Holidays::for(country: 'xx')->get(); expect($holidays) ->toBeArray() ->not()->toBeEmpty(); expect(formatDates($holidays))->toMatchSnapshot(); });
- Run
vendor/bin/pest --update-snapshotsto generate the snapshot. - Verify the generated snapshot in
tests/.pest/snapshots/is correct.
Testing
composer test
Changelog
Please see CHANGELOG for more information on what has changed recently.
Upgrading
Please see UPGRADING for how to upgrade to a new major version.
Contributing
Please see CONTRIBUTING for details.
Security Vulnerabilities
Please review our security policy on how to report security vulnerabilities.
Credits
License
The MIT License (MIT). Please see License File for more information.
spatie/holidays 适用场景与选型建议
spatie/holidays 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 829.64k 次下载、GitHub Stars 达 400, 最近一次更新时间为 2024 年 01 月 17 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「holidays」 「spatie」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 spatie/holidays 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 spatie/holidays 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 spatie/holidays 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
Receive webhooks in Laravel apps
Extended DateTime and Date classes (extending DateTimeImmutable), DateTimeRange and DateRange classes
Easily optimize images using PHP
A basic wrapper for citco/carbon which returns business days between two given dates.
Store your application settings
UK bank holiday and working day Carbon macros backed by the GOV.UK bank holiday feed.
统计信息
- 总下载量: 829.64k
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 402
- 点击次数: 8
- 依赖项目数: 1
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2024-01-17