diff --git a/src/Countries/Australia.php b/src/Countries/Australia.php index 918a33f4f..9047be603 100644 --- a/src/Countries/Australia.php +++ b/src/Countries/Australia.php @@ -6,6 +6,11 @@ class Australia extends Country { + protected function __construct( + protected ?string $region = null, + ) { + } + public function countryCode(): string { return 'au'; @@ -30,6 +35,85 @@ protected function variableHolidays(int $year): array return [ 'Good Friday' => $easter->subDays(2), 'Easter Monday' => $easter->addDay(), + // https://en.wikipedia.org/wiki/Public_holidays_in_Australia + ...array_filter(match($this->region) { + 'act' => [ + 'Canberra Day' => CarbonImmutable::parse("second monday of march {$year}"), + 'Easter Saturday' => $easter->subDay(), + 'Easter Sunday' => $easter, + 'Reconciliation Day' => CarbonImmutable::parse("first monday after or on 27 may {$year}"), + 'King\'s Birthday' => $year >= 2023 ? CarbonImmutable::parse("second monday of june {$year}") : null, + 'Queen\'s Birthday' => $year < 2023 ? CarbonImmutable::parse("second monday of june {$year}") : null, + 'Labour Day' => CarbonImmutable::parse("first monday of october {$year}"), + ], + 'nsw' => [ + 'Easter Saturday' => $easter->subDay(), + 'Easter Sunday' => $easter, + 'King\'s Birthday' => $year >= 2023 ? CarbonImmutable::parse("second monday of june {$year}") : null, + 'Queen\'s Birthday' => $year < 2023 ? CarbonImmutable::parse("second monday of june {$year}") : null, + 'Labour Day' => CarbonImmutable::parse("first monday of october {$year}"), + ], + 'nt' => [ + 'Easter Saturday' => $easter->subDay(), + 'May Day' => CarbonImmutable::parse("first monday of may {$year}"), + 'Picnic Day' => CarbonImmutable::parse("first monday of august {$year}"), + ], + 'qld' => [ + 'The day after Good Friday' => $easter->subDay(), + 'Easter Sunday' => $easter, + 'Labour Day' => CarbonImmutable::parse("first monday of may {$year}"), + 'King\'s Birthday' => $year >= 2023 ? CarbonImmutable::parse("first monday of october {$year}") : null, + 'Queen\'s Birthday' => $year < 2023 ? CarbonImmutable::parse("first monday of october {$year}") : null, + ], + 'sa' => [ + 'Adelaide Cup Day' => $year < 2006 + ? CarbonImmutable::parse("third monday of may {$year}") + : CarbonImmutable::parse("second monday of march {$year}"), + 'The day after Good Friday' => $easter->subDay(), + 'King\'s Birthday' => $year >= 2023 ? CarbonImmutable::parse("second monday of june {$year}") : null, + 'Queen\'s Birthday' => $year < 2023 ? CarbonImmutable::parse("second monday of june {$year}") : null, + 'Labour Day' => CarbonImmutable::parse("first monday of october {$year}"), + ], + 'tas' => [ + 'Eight Hours Day' => CarbonImmutable::parse("second monday of march {$year}"), + 'King\'s Birthday' => $year >= 2023 ? CarbonImmutable::parse("second monday of june {$year}") : null, + 'Queen\'s Birthday' => $year < 2023 ? CarbonImmutable::parse("second monday of june {$year}") : null, + ], + 'vic' => [ + 'Labour Day' => CarbonImmutable::parse("second monday of march {$year}"), + 'Saturday before Easter Sunday' => $easter->subDay(), + 'Easter Sunday' => $easter, + 'King\'s Birthday' => $year >= 2023 ? CarbonImmutable::parse("second monday of june {$year}") : null, + 'Queen\'s Birthday' => $year < 2023 ? CarbonImmutable::parse("second monday of june {$year}") : null, + 'Friday before AFL Grand Final' => $this->fridayBeforeAflGrandFinal($year), + 'Melbourne Cup' => CarbonImmutable::parse("first tuesday of november {$year}"), + ], + 'wa' => [ + 'Labour Day' => CarbonImmutable::parse("first monday of march {$year}"), + 'Easter Sunday' => $easter, + 'Western Australia Day' => CarbonImmutable::parse("first monday of june {$year}"), + // https://www.abc.net.au/news/2022-09-22/queens-birthday-public-holiday-becomes-kings-birthday/101453408 + 'King\'s Birthday' => $year >= 2022 ? CarbonImmutable::parse("last monday of september {$year}") : null, + 'Queen\'s Birthday' => $year < 2022 ? CarbonImmutable::parse("last monday of september {$year}") : null, + ], + default => [], + }), ]; } + + // https://business.vic.gov.au/business-information/public-holidays/victorian-public-holidays-2025 + // https://en.wikipedia.org/wiki/List_of_VFL/AFL_premiers#VFL/AFL_premierships + protected function fridayBeforeAflGrandFinal(int $year): ?CarbonImmutable + { + if ($year < 2015) { + return null; + } + + return match ($year) { + 2015 => CarbonImmutable::parse('2015-10-02'), + 2020 => CarbonImmutable::parse('2020-10-23'), + 2022 => CarbonImmutable::parse('2022-09-23'), + default => CarbonImmutable::parse("last friday of september {$year}"), + }; + } } diff --git a/tests/.pest/snapshots/Countries/AustraliaTest/it_can_calculate_australian_holidays_for_a_specific_year.snap b/tests/.pest/snapshots/Countries/AustraliaTest/it_can_calculate_australian_holidays_for_a_specific_year.snap new file mode 100644 index 000000000..340c74d77 --- /dev/null +++ b/tests/.pest/snapshots/Countries/AustraliaTest/it_can_calculate_australian_holidays_for_a_specific_year.snap @@ -0,0 +1,30 @@ +[ + { + "name": "New Year's Day", + "date": "2025-01-01" + }, + { + "name": "Australia Day", + "date": "2025-01-26" + }, + { + "name": "Good Friday", + "date": "2025-04-18" + }, + { + "name": "Easter Monday", + "date": "2025-04-21" + }, + { + "name": "Anzac Day", + "date": "2025-04-25" + }, + { + "name": "Christmas Day", + "date": "2025-12-25" + }, + { + "name": "Boxing Day", + "date": "2025-12-26" + } +] \ No newline at end of file diff --git a/tests/.pest/snapshots/Countries/AustraliaTest/it_can_calculate_regional_australian_holidays.snap b/tests/.pest/snapshots/Countries/AustraliaTest/it_can_calculate_regional_australian_holidays.snap new file mode 100644 index 000000000..6ccbd6ab5 --- /dev/null +++ b/tests/.pest/snapshots/Countries/AustraliaTest/it_can_calculate_regional_australian_holidays.snap @@ -0,0 +1,54 @@ +[ + { + "name": "New Year's Day", + "date": "2024-01-01" + }, + { + "name": "Australia Day", + "date": "2024-01-26" + }, + { + "name": "Labour Day", + "date": "2024-03-11" + }, + { + "name": "Good Friday", + "date": "2024-03-29" + }, + { + "name": "Saturday before Easter Sunday", + "date": "2024-03-30" + }, + { + "name": "Easter Sunday", + "date": "2024-03-31" + }, + { + "name": "Easter Monday", + "date": "2024-04-01" + }, + { + "name": "Anzac Day", + "date": "2024-04-25" + }, + { + "name": "King's Birthday", + "date": "2024-06-10" + }, + { + "name": "Friday before AFL Grand Final", + "date": "2024-09-27" + }, + { + "name": "Melbourne Cup", + "date": "2024-11-05" + }, + { + "name": "Christmas Day", + "date": "2024-12-25" + }, + { + "name": "Boxing Day", + "date": "2024-12-26" + } +] \ No newline at end of file diff --git a/tests/Countries/AustraliaTest.php b/tests/Countries/AustraliaTest.php index fea311550..568f4e7d6 100644 --- a/tests/Countries/AustraliaTest.php +++ b/tests/Countries/AustraliaTest.php @@ -3,10 +3,11 @@ namespace Spatie\Holidays\Tests\Countries; use Carbon\CarbonImmutable; +use Spatie\Holidays\Countries\Australia; use Spatie\Holidays\Holidays; it('can calculate australian holidays', function () { - CarbonImmutable::setTestNowAndTimezone('2024-01-01', 'Australia/Melbourne'); + CarbonImmutable::setTestNowAndTimezone('2024-01-22', 'Australia/Melbourne'); $holidays = Holidays::for(country: 'au')->get(); @@ -16,3 +17,96 @@ expect(formatDates($holidays))->toMatchSnapshot(); }); + +it('can calculate australian holidays for a specific year', function () { + CarbonImmutable::setTestNowAndTimezone('2024-01-22', 'Australia/Melbourne'); + + $holidays = Holidays::for(country: 'au', year: 2025)->get(); + + expect($holidays) + ->toBeArray() + ->not()->toBeEmpty(); + + expect(formatDates($holidays))->toMatchSnapshot(); +}); + +it('can calculate regional australian holidays', function () { + CarbonImmutable::setTestNowAndTimezone('2024-01-22', 'Australia/Melbourne'); + + $holidays = Holidays::for(Australia::make('vic'))->get(); + + expect($holidays) + ->toBeArray() + ->not()->toBeEmpty(); + + expect(formatDates($holidays))->toMatchSnapshot(); +}); + +it('can calculate the day before afl grand final', function () { + CarbonImmutable::setTestNowAndTimezone('2021-01-22', 'Australia/Melbourne'); + + $holidays = Holidays::for(Australia::make('vic'))->get(); + + expect(findDate($holidays, 'Friday before AFL Grand Final')) + ->toEqual(CarbonImmutable::create(2021, 9, 24)); +}); + +it('can calculate the day before afl grand final during lockdown', function () { + CarbonImmutable::setTestNowAndTimezone('2020-01-22', 'Australia/Melbourne'); + + $holidays = Holidays::for(Australia::make('vic'))->get(); + + expect(findDate($holidays, 'Friday before AFL Grand Final')) + ->toEqual(CarbonImmutable::create(2020, 10, 23)); +}); + +it('does not return the day before afl grand final before 2015', function () { + CarbonImmutable::setTestNowAndTimezone('2014-01-22', 'Australia/Melbourne'); + + $holidays = Holidays::for(Australia::make('vic'))->get(); + + expect(findDate($holidays, 'Friday before AFL Grand Final')) + ->toBeNull(); +}); + +it('returns queen\'s birthday before her death', function () { + CarbonImmutable::setTestNowAndTimezone('2021-01-22', 'Australia/Perth'); + + $holidays = Holidays::for(Australia::make('wa'))->get(); + + expect(findDate($holidays, 'Queen\'s Birthday')) + ->toEqual(CarbonImmutable::create(2021, 9, 27)); + + expect(findDate($holidays, 'King\'s Birthday')) + ->toBeNull(); +}); + +it('returns king\'s birthday after her death', function () { + CarbonImmutable::setTestNowAndTimezone('2022-01-22', 'Australia/Perth'); + + $holidays = Holidays::for(Australia::make('wa'))->get(); + + expect(findDate($holidays, 'Queen\'s Birthday')) + ->toBeNull(); + + expect(findDate($holidays, 'King\'s Birthday')) + ->toEqual(CarbonImmutable::create(2022, 9, 26)); +}); + +it('can calculate Adelaide Cup Day before 2006', function () { + CarbonImmutable::setTestNowAndTimezone('2005-01-22', 'Australia/Adelaide'); + + $holidays = Holidays::for(Australia::make('sa'))->get(); + + expect(findDate($holidays, 'Adelaide Cup Day')) + ->toEqual(CarbonImmutable::create(2005, 5, 16)); +}); + +it('can calculate Adelaide Cup Day after 2006', function () { + CarbonImmutable::setTestNowAndTimezone('2007-01-22', 'Australia/Adelaide'); + + $holidays = Holidays::for(Australia::make('sa'))->get(); + + expect(findDate($holidays, 'Adelaide Cup Day')) + ->toEqual(CarbonImmutable::create(2007, 3, 12)); +}); diff --git a/tests/Pest.php b/tests/Pest.php index 310516cb7..b17024094 100644 --- a/tests/Pest.php +++ b/tests/Pest.php @@ -20,3 +20,14 @@ function formatDates(array $holidays): array return $holidays; } + +function findDate(array $holidays, string $name): ?Carbon\CarbonImmutable +{ + foreach ($holidays as $holiday) { + if ($holiday['name'] === $name) { + return $holiday['date']; + } + } + + return null; +}