diff --git a/src/Countries/Jamaica.php b/src/Countries/Jamaica.php new file mode 100644 index 000000000..a6c955580 --- /dev/null +++ b/src/Countries/Jamaica.php @@ -0,0 +1,84 @@ +fixedHolidays(), + $this->variableHolidays($year), + $this->observedHolidays($year) + ); + + return $holidays; + } + + /** @return array */ + protected function fixedHolidays(): array + { + $holidays = [ + 'New Year\'s Day' => '01-01', + 'Labour Day' => '05-23', + 'Emancipation Day' => '08-01', + 'Independence Day' => '08-06', + 'Christmas Day' => '12-25', + 'Boxing Day' => '12-26', + ]; + + return $holidays; + } + + /** @return array */ + protected function variableHolidays(int $year): array + { + $easter = $this->easter($year); + $heroesDay = new CarbonImmutable("third monday of October $year"); + + return [ + 'Ash Wednesday' => $easter->subDays(46), + 'Good Friday' => $easter->subDays(2), + 'Easter Monday' => $easter->addDay(), + 'National Heroes Day' => $heroesDay, + ]; + } + + /** @return array */ + protected function observedHolidays(int $year): array + { + + $observedHolidays = []; + + foreach ($this->fixedHolidays() as $name => $date) { + $date = CarbonImmutable::parse("$year-$date"); + + // If any holiday falls on a Sunday, then it is observed on Monday + if($date->dayOfWeek === 0) { + $observedHolidays["{$name} Observed"] = $date->next(CarbonImmutable::MONDAY); + } + + // If Labour Day falls on a Saturday, then it is observed on Monday + if($name == 'Labour Day' && $date->dayOfWeek === 6) { + $observedHolidays["{$name} Observed"] = $date->next(CarbonImmutable::MONDAY); + } + + // If Boxing Day falls on a Monday, then it is observed on Tuesday (Christmas Day is observed on Monday) + // https://jis.gov.jm/observance-public-holidays-christmas-day-monday-december-26th-boxing-day-tuesday-december-27th/ + if ($name == 'Boxing Day' && $date->dayOfWeek === 1) { + $observedHolidays["{$name} Observed"] = $date->next(CarbonImmutable::TUESDAY); + } + } + + return $observedHolidays; + } +} diff --git a/tests/.pest/snapshots/Countries/JamaicaTest/it_can_calculate_jamaican_holidays.snap b/tests/.pest/snapshots/Countries/JamaicaTest/it_can_calculate_jamaican_holidays.snap new file mode 100644 index 000000000..3d71e806c --- /dev/null +++ b/tests/.pest/snapshots/Countries/JamaicaTest/it_can_calculate_jamaican_holidays.snap @@ -0,0 +1,42 @@ +[ + { + "name": "New Year's Day", + "date": "2024-01-01" + }, + { + "name": "Ash Wednesday", + "date": "2024-02-14" + }, + { + "name": "Good Friday", + "date": "2024-03-29" + }, + { + "name": "Easter Monday", + "date": "2024-04-01" + }, + { + "name": "Labour Day", + "date": "2024-05-23" + }, + { + "name": "Emancipation Day", + "date": "2024-08-01" + }, + { + "name": "Independence Day", + "date": "2024-08-06" + }, + { + "name": "National Heroes Day", + "date": "2024-10-21" + }, + { + "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/JamaicaTest.php b/tests/Countries/JamaicaTest.php new file mode 100644 index 000000000..1ea7b0237 --- /dev/null +++ b/tests/Countries/JamaicaTest.php @@ -0,0 +1,34 @@ +get(); + + expect($holidays) + ->toBeArray() + ->not()->toBeEmpty(); + + expect(formatDates($holidays))->toMatchSnapshot(); +}); + +it('can calculate observed holidays based on year', function () { + + // Check for Observed New Year's Day + $holidays = Holidays::for(country: 'jm', year: 2023)->get(); + expect(array_search('New Year\'s Day Observed', array_column($holidays, 'name')))->toBeInt(); + + // Check for Observed Labour Day + $holidays = Holidays::for(country: 'jm', year: 2020)->get(); + expect(array_search('Labour Day Observed', array_column($holidays, 'name')))->toBeInt(); + + // Check that there is no Observerd New Year's Day + $holidays = Holidays::for(country: 'jm', year: 2024)->get(); + expect(array_search('Labour Day Observed', array_column($holidays, 'name')))->toBeFalse(); + +});