diff --git a/src/Countries/France.php b/src/Countries/France.php new file mode 100644 index 000000000..449d13f57 --- /dev/null +++ b/src/Countries/France.php @@ -0,0 +1,79 @@ + '01-01', + 'Fête du Travail' => '05-01', + 'Victoire 1945' => '05-08', + 'Fête Nationale' => '07-14', + 'Assomption' => '08-15', + 'Toussaint' => '11-01', + 'Armistice 1918' => '11-11', + 'Noël' => '12-25', + ], + $this->variableHolidays($year), + $this->regionHolidays()); + } + + /** @return array */ + protected function variableHolidays(int $year): array + { + $easter = CarbonImmutable::createFromTimestamp(easter_date($year)) + ->setTimezone('Europe/Paris'); + + $holidays = [ + 'Lundi de Pâques' => $easter->addDay(), + 'Ascension' => $easter->addDays(39), + 'Lundi de Pentecôte' => $easter->addDays(50), + ]; + + if (in_array($this->region, ['FR-57', 'FR-67', 'FR-68'])) { + $holidays['Vendredi Saint'] = $easter->subDays(2); + } + + return $holidays; + } + + /** @return array */ + protected function regionHolidays(): array + { + switch ($this->region) { + case 'FR-57': + case 'FR-67': + case 'FR-68': + return ['Saint-Étienne' => '12-26']; + case 'FR-971': + case 'FR-MF': + return ['Abolition de l\'esclavage' => '05-27']; + case 'FR-972': + return ['Abolition de l\'esclavage' => '05-22']; + case 'FR-973': + return ['Abolition de l\'esclavage' => '06-10']; + case 'FR-974': + return ['Abolition de l\'esclavage' => '12-20']; + case 'FR-976': + return ['Abolition de l\'esclavage' => '04-27']; + case 'FR-BL': + return ['Abolition de l\'esclavage' => '10-09']; + } + + return []; + } +} diff --git a/tests/.pest/snapshots/Countries/FranceTest/it_can_calculate_french_date_based_regional_holidays.snap b/tests/.pest/snapshots/Countries/FranceTest/it_can_calculate_french_date_based_regional_holidays.snap new file mode 100644 index 000000000..5256f894b --- /dev/null +++ b/tests/.pest/snapshots/Countries/FranceTest/it_can_calculate_french_date_based_regional_holidays.snap @@ -0,0 +1,50 @@ +[ + { + "name": "Jour de l'An", + "date": "2024-01-01" + }, + { + "name": "Lundi de P\u00e2ques", + "date": "2024-04-01" + }, + { + "name": "F\u00eate du Travail", + "date": "2024-05-01" + }, + { + "name": "Victoire 1945", + "date": "2024-05-08" + }, + { + "name": "Ascension", + "date": "2024-05-09" + }, + { + "name": "Lundi de Pentec\u00f4te", + "date": "2024-05-20" + }, + { + "name": "F\u00eate Nationale", + "date": "2024-07-14" + }, + { + "name": "Assomption", + "date": "2024-08-15" + }, + { + "name": "Abolition de l'esclavage", + "date": "2024-10-09" + }, + { + "name": "Toussaint", + "date": "2024-11-01" + }, + { + "name": "Armistice 1918", + "date": "2024-11-11" + }, + { + "name": "No\u00ebl", + "date": "2024-12-25" + } +] \ No newline at end of file diff --git a/tests/.pest/snapshots/Countries/FranceTest/it_can_calculate_french_easter_based_region_holidays.snap b/tests/.pest/snapshots/Countries/FranceTest/it_can_calculate_french_easter_based_region_holidays.snap new file mode 100644 index 000000000..4dd52f185 --- /dev/null +++ b/tests/.pest/snapshots/Countries/FranceTest/it_can_calculate_french_easter_based_region_holidays.snap @@ -0,0 +1,54 @@ +[ + { + "name": "Jour de l'An", + "date": "2024-01-01" + }, + { + "name": "Vendredi Saint", + "date": "2024-03-29" + }, + { + "name": "Lundi de P\u00e2ques", + "date": "2024-04-01" + }, + { + "name": "F\u00eate du Travail", + "date": "2024-05-01" + }, + { + "name": "Victoire 1945", + "date": "2024-05-08" + }, + { + "name": "Ascension", + "date": "2024-05-09" + }, + { + "name": "Lundi de Pentec\u00f4te", + "date": "2024-05-20" + }, + { + "name": "F\u00eate Nationale", + "date": "2024-07-14" + }, + { + "name": "Assomption", + "date": "2024-08-15" + }, + { + "name": "Toussaint", + "date": "2024-11-01" + }, + { + "name": "Armistice 1918", + "date": "2024-11-11" + }, + { + "name": "No\u00ebl", + "date": "2024-12-25" + }, + { + "name": "Saint-\u00c9tienne", + "date": "2024-12-26" + } +] \ No newline at end of file diff --git a/tests/.pest/snapshots/Countries/FranceTest/it_can_calculate_french_holidays.snap b/tests/.pest/snapshots/Countries/FranceTest/it_can_calculate_french_holidays.snap new file mode 100644 index 000000000..f89d17309 --- /dev/null +++ b/tests/.pest/snapshots/Countries/FranceTest/it_can_calculate_french_holidays.snap @@ -0,0 +1,46 @@ +[ + { + "name": "Jour de l'An", + "date": "2024-01-01" + }, + { + "name": "Lundi de P\u00e2ques", + "date": "2024-04-01" + }, + { + "name": "F\u00eate du Travail", + "date": "2024-05-01" + }, + { + "name": "Victoire 1945", + "date": "2024-05-08" + }, + { + "name": "Ascension", + "date": "2024-05-09" + }, + { + "name": "Lundi de Pentec\u00f4te", + "date": "2024-05-20" + }, + { + "name": "F\u00eate Nationale", + "date": "2024-07-14" + }, + { + "name": "Assomption", + "date": "2024-08-15" + }, + { + "name": "Toussaint", + "date": "2024-11-01" + }, + { + "name": "Armistice 1918", + "date": "2024-11-11" + }, + { + "name": "No\u00ebl", + "date": "2024-12-25" + } +] \ No newline at end of file diff --git a/tests/Countries/FranceTest.php b/tests/Countries/FranceTest.php new file mode 100644 index 000000000..e70d919be --- /dev/null +++ b/tests/Countries/FranceTest.php @@ -0,0 +1,43 @@ +get(); + + expect($holidays) + ->toBeArray() + ->not()->toBeEmpty(); + + expect(formatDates($holidays))->toMatchSnapshot(); +}); + +it('can calculate french easter based region holidays', function () { + CarbonImmutable::setTestNowAndTimezone('2024-01-01'); + + $holidays = Holidays::for(France::make('FR-57'))->get(); + + expect($holidays) + ->toBeArray() + ->not()->toBeEmpty(); + + expect(formatDates($holidays))->toMatchSnapshot(); +}); + +it('can calculate french date based regional holidays', function () { + CarbonImmutable::setTestNowAndTimezone('2024-01-01'); + + $holidays = Holidays::for(France::make('FR-BL'))->get(); + + expect($holidays) + ->toBeArray() + ->not()->toBeEmpty(); + + expect(formatDates($holidays))->toMatchSnapshot(); +});