Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Holidays Laravel Package

spatie/holidays

Calculate public holidays for supported countries using ISO codes or country classes. Get an array of Holiday objects with name, CarbonImmutable date, and type (e.g., national). PHP 8.4+ package by Spatie, with extensible country definitions.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require spatie/holidays
    

    Requires PHP 8.4+.

  2. First Use Case: Fetch holidays for a country (e.g., Belgium) in the current year:

    use Spatie\Holidays\Holidays;
    
    $holidays = Holidays::for('be')->get();
    foreach ($holidays as $holiday) {
        echo $holiday->name . ' (' . $holiday->date->format('Y-m-d') . ')';
    }
    

    Outputs all Belgian holidays with their names and dates.

  3. Key Entry Points:

    • Holidays::for('country_code')->get(): Get all holidays for a country.
    • Holidays::for('country_code')->isHoliday('2024-01-01'): Check if a specific date is a holiday.
    • Holidays::for('country_code')->getUpcoming(3): Get the next 3 upcoming holidays.

Where to Look First

  • Country Support: Check supported countries for coverage.
  • Documentation: Focus on the Usage section in the README for core methods.
  • Examples: Use the getInRange(), getLongWeekends(), and getName() methods for common workflows.

Implementation Patterns

Core Workflows

  1. Fetching Holidays for Business Logic:

    // Check if a date is a holiday (e.g., for leave approval)
    if (Holidays::for('us')->isHoliday($request->date)) {
        return back()->withError('Holiday detected. Approval denied.');
    }
    
  2. Date Range Filtering:

    // Get holidays for Q1 2024 (e.g., for scheduling)
    $q1Holidays = Holidays::for('jp')->getInRange('2024-01-01', '2024-03-31');
    
  3. Localization:

    // Fetch holidays in French (e.g., for multilingual apps)
    $frHolidays = Holidays::for('ca', locale: 'fr')->get();
    
  4. Regional Holidays:

    // Germany has state-specific holidays (e.g., for regional events)
    $bavarianHolidays = Holidays::for('de', region: 'DE-BW')->get();
    
  5. Long Weekends for Travel Apps:

    // Identify long weekends (e.g., for travel promotions)
    $longWeekends = Holidays::for('au')->getLongWeekends();
    foreach ($longWeekends as $weekend) {
        echo "Weekend: {$weekend->startDate} to {$weekend->endDate}";
    }
    

Integration Tips

  • Caching: Cache holiday results for performance (e.g., using Laravel's cache):

    $holidays = Cache::remember("holidays_{$country}_{$year}", now()->addYear(), function () use ($country, $year) {
        return Holidays::for($country, year: $year)->get();
    });
    
  • API Responses: Serialize holidays for JSON APIs:

    return response()->json(Holidays::for('in')->get());
    
  • Validation: Use holidays to validate date ranges (e.g., in forms):

    $validator->rule(function ($attribute, $value, $fail) {
        if (Holidays::for('gb')->isHoliday($value)) {
            $fail('Holidays are not allowed.');
        }
    });
    
  • Testing: Mock holidays in tests:

    $this->mock(Holidays::class, function ($mock) {
        $mock->shouldReceive('for')->andReturnSelf();
        $mock->shouldReceive('isHoliday')->andReturn(true);
    });
    

Gotchas and Tips

Pitfalls

  1. Country Code Sensitivity:

    • Use ISO 3166-1 alpha-2 codes (e.g., 'us' for USA, not 'usa').
    • Verify support with Holidays::has('country_code').
  2. Year Range Limits:

    • Some countries (e.g., those using lunar calendars) have predefined year ranges. Attempting to fetch holidays outside this range may return empty results or errors.
    • Example: Ethiopia's holidays are only supported up to 2037.
  3. Regional Holiday Overrides:

    • Regional holidays (e.g., Germany's DE-BW) override national holidays if they conflict. Always specify a region if needed.
  4. Date Formatting:

    • The package uses CarbonImmutable for dates. Ensure your code handles immutable dates (e.g., avoid modifying them directly).
  5. Locale Fallbacks:

    • If a locale isn’t supported, the package falls back to the default language. Check available locales in the translations directory.
  6. Observed Holidays:

    • Some countries (e.g., UK) move holidays to the next weekday if they fall on a weekend. The HasObservedHolidays trait handles this, but custom logic may be needed for edge cases.

Debugging Tips

  1. Empty Results:

    • Check if the country is supported: Holidays::has('xx').
    • Verify the year is within the supported range (e.g., for lunar calendars).
  2. Missing Regional Holidays:

    • Ensure the region code is correct (e.g., 'DE-BW' for Bavaria, not 'bw').
    • Use Country::regions() to list valid regions for a country.
  3. Date Mismatches:

    • Use Holidays::for('country')->getName('2024-01-01') to debug holiday names/dates.
    • For lunar calendars, ensure your lookup tables are up to date.
  4. Performance:

    • Avoid fetching holidays in loops. Cache results or fetch once per request.
    • For large date ranges, use getInRange() instead of filtering after fetching all holidays.

Extension Points

  1. Custom Holiday Logic:

    • Extend the Country class to add support for unsupported countries:
      class MyCountry extends Country {
          public function countryCode(): string { return 'xx'; }
          protected function allHolidays(int $year): array {
              return [Holiday::national('Custom Holiday', "{$year}-12-25")];
          }
      }
      
    • Register the new country in CountryRegistry.php.
  2. Calendar Systems:

    • Add support for non-Gregorian calendars (e.g., Islamic, Chinese) by implementing the relevant trait (e.g., IslamicCalendar) and defining lookup tables.
  3. Holiday Types:

    • Extend the HolidayType enum or add custom types by modifying the Holiday class.
  4. Translations:

    • Add translations for unsupported locales by creating JSON files in lang/{countryCode}/{locale}/holidays.json.
  5. Testing:

    • Use Pest snapshots to verify holiday calculations:
      expect(formatDates($holidays))->toMatchSnapshot();
      
    • Run vendor/bin/pest --update-snapshots to update snapshots after changes.

Config Quirks

  • No Configuration File: The package is zero-config. All settings are handled via method parameters.
  • Default Year: If no year is provided, the current year is used.
  • Default Locale: Falls back to the country’s default language if the requested locale isn’t available.

Pro Tips

  1. Combine with Carbon:

    use Carbon\CarbonImmutable;
    
    $holidayDate = CarbonImmutable::parse('2024-01-01');
    if (Holidays::for('be')->isHoliday($holidayDate)) {
        // Logic for holidays
    }
    
  2. Group Holidays by Type:

    $national = array_filter($holidays, fn($h) => $h->type === HolidayType::National);
    $regional = array_filter($holidays, fn($h) => $h->type === HolidayType::Regional);
    
  3. Dynamic Year Handling:

    $year = now()->year;
    $holidays = Holidays::for('in', year: $year)->get();
    
  4. Holiday-Free Date Ranges:

    function getHolidayFreeDates(string $country, string $start, string $end): array {
        $allDates = collect(range($start, $end));
        $holidays = Holidays::for($country)->getInRange($start, $end);
        return $allDates->reject(fn($date) => $holidays->contains(fn($h) => $h->date->
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
codraw/entity-migrator
codraw/doctrine-extra
codraw/aws-tool-kit
codraw/validator
codraw/workflow
codraw/open-api
codraw/cron-job
codraw/process
codraw/log
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony