Skip to content

Commit

Permalink
move Observed holiday logic to separate trait
Browse files Browse the repository at this point in the history
Nielsvanpach committed Feb 9, 2024
1 parent 2f9a616 commit a564053
Showing 6 changed files with 140 additions and 131 deletions.
54 changes: 54 additions & 0 deletions src/Concerns/Observable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

namespace Spatie\Holidays\Concerns;

use Carbon\CarbonImmutable;
use Carbon\CarbonInterface;

trait Observable
{
protected function observedChristmasDay(int $year): ?CarbonInterface
{
$christmasDay = (new CarbonImmutable($year.'-12-25'))->startOfDay();

return match ($christmasDay->dayName) {
'Saturday' => $christmasDay->next('monday'),
'Sunday' => $christmasDay->next('tuesday'),
default => null,
};
}

protected function observedBoxingDay(int $year): ?CarbonInterface
{
$christmasDay = (new CarbonImmutable($year.'-12-25'))->startOfDay();
$boxingDay = $christmasDay->addDay();

return match ($christmasDay->dayName) {
'Friday' => $boxingDay->next('monday'),
'Saturday' => $boxingDay->next('tuesday'),
default => null,
};
}

protected function weekendToNextMonday(string|CarbonInterface $date, int $year): ?CarbonInterface
{
if (is_string($date)) {
$date = CarbonImmutable::createFromFormat('Y-m-d', "{$year}-{$date}")->startOfDay();
}

if ($date->isWeekend()) {
return $date->next('monday');
}

return null;
}

protected function sundayToNextMonday(CarbonInterface $date): ?CarbonInterface
{
if ($date->isSunday()) {
return $date->next('monday');
}

return null;
}
}
54 changes: 18 additions & 36 deletions src/Countries/Ghana.php
Original file line number Diff line number Diff line change
@@ -4,9 +4,12 @@

use Carbon\CarbonImmutable;
use Carbon\CarbonInterface;
use Spatie\Holidays\Concerns\Observable;

class Ghana extends Country
{
use Observable;

public function countryCode(): string
{
return 'gh';
@@ -20,7 +23,7 @@ protected function allHolidays(int $year): array
);
}

/** @return array<string, CarbonInterface> */
/** @return array<string, string|CarbonInterface> */
protected function observedHolidays(int $year): array
{
$holidays = [
@@ -30,16 +33,23 @@ protected function observedHolidays(int $year): array
'May Day' => '05-01',
'Founder\'s Day' => '08-04',
'Kwame Nkrumah Memorial Day' => '09-21',
'Christmas Day' => '12-25',
'Boxing Day' => '12-26',
];

$holidays = array_map(function ($holiday) use ($year) {
return $this->observed($holiday, $year);
}, $holidays);
foreach ($holidays as $name => $date) {
$observedDay = match ($name) {
'Christmas Day' => $this->observedChristmasDay($year),
'Boxing Day' => $this->observedBoxingDay($year),
default => $this->weekendToNextMonday($date, $year),
};

if ($observedDay) {
$holidays[$name] = $observedDay;
}
}

return array_merge($holidays, [
'Christmas Day' => $this->observedChristmasDay($year),
'Boxing Day' => $this->observedBoxingDay($year),
]);
return $holidays;
}

protected function observed(string $date, int $year): CarbonInterface
@@ -53,34 +63,6 @@ protected function observed(string $date, int $year): CarbonInterface
return $holiday;
}

protected function christmas(int $year): CarbonInterface
{
return (new CarbonImmutable($year.'-12-25'))->startOfDay();
}

protected function observedChristmasDay(int $year): CarbonInterface
{
$christmasDay = $this->christmas($year);

return match ($christmasDay->dayName) {
'Saturday' => $christmasDay->next('monday'),
'Sunday' => $christmasDay->next('tuesday'),
default => $christmasDay,
};
}

protected function observedBoxingDay(int $year): CarbonInterface
{
$christmasDay = $this->christmas($year);
$boxingDay = new CarbonImmutable($year.'-12-26');

return match ($christmasDay->dayName) {
'Friday' => $boxingDay->next('monday'),
'Saturday' => $boxingDay->next('tuesday'),
default => $boxingDay,
};
}

/** @return array<string, string|CarbonInterface> */
protected function variableHolidays(int $year): array
{
10 changes: 4 additions & 6 deletions src/Countries/Ireland.php
Original file line number Diff line number Diff line change
@@ -16,10 +16,6 @@ protected function allHolidays(int $year): array
return array_merge([
'New Year\'s Day' => '01-01',
'Saint Patrick\'s Day' => '03-17',
'May Public Holiday' => 'first monday of May',
'June Public Holiday' => 'first monday of June',
'August Public Holiday' => 'first monday of August',
'October Public Holiday' => 'last monday of October',
'Christmas Day' => '12-25',
'Saint Stephen\'s Day' => '12-26',
], $this->variableHolidays($year));
@@ -28,10 +24,12 @@ protected function allHolidays(int $year): array
/** @return array<string, string|CarbonImmutable> */
protected function variableHolidays(int $year): array
{
$easter = $this->easter($year);

$variableHolidays = [
'Easter Monday' => $this->easter($year)->addDay(),
'May Public Holiday' => 'first monday of May',
'June Public Holiday' => 'first monday of June',
'August Public Holiday' => 'first monday of August',
'October Public Holiday' => 'last monday of October',
];

if ($year >= 2023) {
19 changes: 14 additions & 5 deletions src/Countries/Japan.php
Original file line number Diff line number Diff line change
@@ -2,6 +2,8 @@

namespace Spatie\Holidays\Countries;

use Carbon\CarbonImmutable;

class Japan extends Country
{
public function countryCode(): string
@@ -11,24 +13,31 @@ public function countryCode(): string

protected function allHolidays(int $year): array
{
return [
return array_merge([
'元日' => '01-01', // New Year's Day
'成人の日' => 'second monday of january',
'建国記念の日' => '02-11', // Foundation Day
'天皇誕生日' => '02-23', // Emperor's Birthday
'春分の日' => '03-20', // Vernal Equinox Day *Decided each year; rarely on 03-21
'昭和の日' => '04-29', // Showa Day
'憲法記念日' => '05-03', // Constitution Day
'みどりの日' => '05-04', // Greenery Day
'こどもの日' => '05-05', // Children's Day
'海の日' => 'third monday of july',
'山の日' => '08-11', // Mountain Day
'敬老の日' => 'third monday of september',
'秋分の日' => '09-23', // Autumnal Equinox Day *Decided each year; rarely on 09-22
'スポーツの日' => 'second monday of october',
'文化の日' => '11-03', // Culture Day
'勤労感謝の日' => '11-23', // Labor Thanksgiving Day

], $this->variableHolidays());
}

/** @return array<string, string> */
protected function variableHolidays(): array
{
return [
'成人の日' => 'second monday of january',
'海の日' => 'third monday of july',
'敬老の日' => 'third monday of september',
'スポーツの日' => 'second monday of october',
];
}
}
4 changes: 2 additions & 2 deletions src/Countries/NorthernIreland.php
Original file line number Diff line number Diff line change
@@ -20,8 +20,8 @@ protected function allHolidays(int $year): array
$this->earlyMayBankHoliday($year),
$this->battleOfTheBoyne($year),
[
'Spring bank holiday' => new CarbonImmutable("last monday of may {$year}", 'Europe/London'),
'Summer bank holiday' => new CarbonImmutable("last monday of august {$year}", 'Europe/London'),
'Spring bank holiday' => 'last monday of may',
'Summer bank holiday' => 'last monday of august',
],
$this->christmasDay($year),
$this->boxingDay($year),
130 changes: 48 additions & 82 deletions src/Countries/Wales.php
Original file line number Diff line number Diff line change
@@ -4,130 +4,96 @@

use Carbon\CarbonImmutable;
use Carbon\CarbonInterface;
use Spatie\Holidays\Concerns\Observable;

class Wales extends Country
{
use Observable;

public function countryCode(): string
{
return 'gb-cym';
}

/** @return array<string, CarbonInterface> */
protected function christmasDay(int $year): array
/** @return array<string, string|CarbonInterface> */
protected function allHolidays(int $year): array
{
$christmasDay = new CarbonImmutable($year.'-12-25', 'Europe/London');
$key = 'Christmas Day';

if ($christmasDay->isSaturday()) {
$key .= ' (substitute day)';
$christmasDay = $christmasDay->next('monday');
}

if ($christmasDay->isSunday()) {
$key .= ' (substitute day)';
$christmasDay = $christmasDay->next('tuesday');
}

return [$key => $christmasDay];
return array_merge(
$this->observedHolidays($year),
$this->earlyMayBankHoliday($year),
$this->variableHolidays($year),
$this->oneOffHolidays($year),
);
}

/** @return array<string, CarbonInterface> */
protected function boxingDay(int $year): array
/** @return array<string, string|CarbonInterface> */
protected function observedHolidays(int $year): array
{
$christmasDay = new CarbonImmutable($year.'-12-25', 'Europe/London');
$boxingDay = new CarbonImmutable($year.'-12-26', 'Europe/London');
$key = 'Boxing Day';

if ($christmasDay->isFriday()) {
$key .= ' (substitute day)';
$boxingDay = $boxingDay->next('monday');
}
$holidays = [
'New Year\'s Day' => '01-01',
'Christmas Day' => '12-25',
'Boxing Day' => '12-26',
];

if ($christmasDay->isSaturday()) {
$key .= ' (substitute day)';
$boxingDay = $boxingDay->next('tuesday');
foreach ($holidays as $name => $date) {
$observedDay = match ($name) {
'Christmas Day' => $this->observedChristmasDay($year),
'Boxing Day' => $this->observedBoxingDay($year),
default => $this->weekendToNextMonday($date, $year),
};

if ($observedDay) {
$holidays[$name.' (substitute day)'] = $observedDay;
unset($holidays[$name]);
}
}

return [$key => $boxingDay];
return $holidays;
}

/** @return array<string, CarbonInterface> */
protected function newYearsDay(int $year): array
/** @return array<string, string|CarbonImmutable> */
protected function variableHolidays(int $year): array
{
$newYearsDay = new CarbonImmutable($year.'-01-01', 'Europe/London');
$key = 'New Year\'s Day';
$easterSunday = $this->easter($year);

if ($newYearsDay->isWeekend()) {
$key .= ' (substitute day)';
$newYearsDay = $newYearsDay->next('monday');
}
$goodFriday = $easterSunday->subDays(2);
$easterMonday = $easterSunday->addDay();

return [$key => $newYearsDay];
return [
'Good Friday' => $goodFriday,
'Easter Monday' => $easterMonday,
'Spring bank holiday' => 'last monday of may',
'Summer bank holiday' => 'last monday of august',
];
}

/** @return array<string, CarbonInterface> */
/** @return array<string, string|CarbonInterface> */
protected function earlyMayBankHoliday(int $year): array
{
if ($year === 2020) {
return [
'Early May bank holiday (VE day)' => new CarbonImmutable('2020-05-08', 'Europe/London'),
'Early May bank holiday (VE day)' => (new CarbonImmutable('2020-05-08'))->startOfDay(),
];
}

if ($year === 2023) {
return [
'Bank holiday for the coronation of King Charles III' => new CarbonImmutable('2020-05-08', 'Europe/London'),
'Bank holiday for the coronation of King Charles III' => (new CarbonImmutable('2020-05-08'))->startOfDay(),
];
}

return ['Early May bank holiday' => new CarbonImmutable("first monday of may {$year}", 'Europe/London')];
return ['Early May bank holiday' => 'first monday of may'];
}

/**
* @return array|CarbonImmutable[]
*/
/** @return array<string, string|CarbonInterface> */
protected function oneOffHolidays(int $year): array
{
return match ($year) {
2022 => [
'Platinum Jubilee bank holiday' => new CarbonImmutable('2022-06-03', 'Europe/London'),
'Bank Holiday for the State Funeral of Queen Elizabeth II' => new CarbonImmutable('2022-09-19', 'Europe/London'),
'Platinum Jubilee bank holiday' => (new CarbonImmutable('2022-06-03'))->startOfDay(),
'Bank Holiday for the State Funeral of Queen Elizabeth II' => (new CarbonImmutable('2022-09-19'))->startOfDay(),
],
default => [],
};
}

/** @return array<string, CarbonInterface> */
protected function allHolidays(int $year): array
{
$regularHolidays = array_merge(
$this->newYearsDay($year),
$this->earlyMayBankHoliday($year),
[
'Spring bank holiday' => new CarbonImmutable("last monday of may {$year}", 'Europe/London'),
'Summer bank holiday' => new CarbonImmutable("last monday of august {$year}", 'Europe/London'),
],
$this->christmasDay($year),
$this->boxingDay($year),
$this->variableHolidays($year)
);

$oneOffHolidays = $this->oneOffHolidays($year);

return array_merge($regularHolidays, $oneOffHolidays);
}

/** @return array<string, CarbonImmutable> */
protected function variableHolidays(int $year): array
{
$easterSunday = $this->easter($year);

$goodFriday = $easterSunday->subDays(2);
$easterMonday = $easterSunday->addDay();

return [
'Good Friday' => $goodFriday,
'Easter Monday' => $easterMonday,
];
}
}

0 comments on commit a564053

Please sign in to comment.