From 795598951ab28745f66886089a38193f825e6559 Mon Sep 17 00:00:00 2001 From: Olin <45310038+OlinB@users.noreply.github.com> Date: Tue, 2 Apr 2024 17:22:49 +0200 Subject: [PATCH 1/2] Fix the Holidays in French speaking Switzerland (#217) * correct Geneva holidays using Art. 32 from https://silgeneve.ch/legis/index.aspx as reference * add missing Vaud (Switzerland) holiday * add missing Neuchatel (Switzerland) holidays reference: https://www.ne.ch/themes/travail/Pages/jours-feries.aspx * add french translations to missing holidays * correct the Holidays for Fribourg (Switzerland) and add a special locale for the reformed part of Fribourg because it has different holidays source: https://www.fr.ch/travail-et-entreprises/employes/jours-feries * Add missing Italian translations for swiss holidays * Add the new regions to the REGIONS array * Tests and add 2 more missing holidays (CH) --- lang/switzerland/fr/holidays.json | 9 ++++- lang/switzerland/it/holidays.json | 9 ++++- src/Countries/Switzerland.php | 56 ++++++++++++++++++++++++++++++- 3 files changed, 71 insertions(+), 3 deletions(-) diff --git a/lang/switzerland/fr/holidays.json b/lang/switzerland/fr/holidays.json index 28a04b822..44123e041 100644 --- a/lang/switzerland/fr/holidays.json +++ b/lang/switzerland/fr/holidays.json @@ -1,7 +1,9 @@ { "Neujahr": "Nouvel An", + "Neujahrs nächster tag": "Lendemain du Nouvel An", "Berchtoldstag": "Saint-Berthold", "Heilige Drei Könige": "Épiphanie", + "Neuenburger Republik tag": "Instauration de la République de Neuchâtel", "Josefstag": "Saint-Joseph", "Karfreitag": "Vendredi saint", "Ostermontag": "Lundi de Pâques", @@ -10,10 +12,15 @@ "Pfingstmontag": "Lundi de Pentecôte", "Fronleichnam": "Fête-Dieu", "Bundesfeier": "Fête nationale", + "Bundesfeier nächster tag": "Lendemain de la Fête nationale", "Maria Himmelfahrt": "Assomption", + "Genfer Fasten": "Jeûne genevois", "Buss- und Bettag": "Jeûne fédéral", + "Buss- und Bettag Montag": "Lundi du Jeûne fédéral", "Allerheiligen": "Toussaint", "Maria Empfängnis": "Immaculée Conception", "Weihnachtstag": "Noël", - "Stephanstag": "Saint-Étienne" + "Weihnachtsnächstertag": "Lendemain de Noël", + "Stephanstag": "Saint-Étienne", + "Genf Republik tag": "Instauration de la République de Genève" } diff --git a/lang/switzerland/it/holidays.json b/lang/switzerland/it/holidays.json index e62ec667e..11ab48f23 100644 --- a/lang/switzerland/it/holidays.json +++ b/lang/switzerland/it/holidays.json @@ -1,7 +1,9 @@ { "Neujahr": "Capodanno", + "Neujahrs nächster tag": "Il giorno dopo Capodanno", "Berchtoldstag": "San Silvestro", "Heilige Drei Könige": "Epifania", + "Neuenburger Republik tag": "Istituzione della Repubblica di Neuchâtel", "Josefstag": "San Giuseppe", "Karfreitag": "Venerdì Santo", "Ostermontag": "Lunedì di Pasqua", @@ -10,10 +12,15 @@ "Pfingstmontag": "Lunedì di Pentecoste", "Fronleichnam": "Corpus Domini", "Bundesfeier": "Festa nazionale", + "Bundesfeier nächster tag": "Il giorno dopo la festa nazionale", "Maria Himmelfahrt": "Assunzione", + "Genfer Fasten": "Jeûne genevois", "Buss- und Bettag": "Digiuno federale", + "Buss- und Bettag Montag": "Digiuno federale Lunedì", "Allerheiligen": "Ognissanti", "Maria Empfängnis": "Immacolata Concezione", "Weihnachtstag": "Natale", - "Stephanstag": "Santo Stefano" + "Weihnachtsnächstertag": "Il giorno dopo la festa di Natale", + "Stephanstag": "Santo Stefano", + "Genf Republik tag": "Istituzione della Repubblica di Ginevra" } diff --git a/src/Countries/Switzerland.php b/src/Countries/Switzerland.php index d9305fbf0..60b3b6881 100644 --- a/src/Countries/Switzerland.php +++ b/src/Countries/Switzerland.php @@ -19,6 +19,8 @@ class Switzerland extends Country implements HasTranslations 'ch-bs', 'ch-be', 'ch-fr', + 'ch-fr-c', + 'ch-fr-r', 'ch-ge', 'ch-gl', 'ch-gr', @@ -42,10 +44,14 @@ class Switzerland extends Country implements HasTranslations private const NEW_YEARS_DAY = 'Neujahr'; + private const NEW_YEARS_NEXT_DAY = 'Neujahrs nächster tag'; + private const BERCHTOLDS_DAY = 'Berchtoldstag'; private const THREE_KINGS_DAY = 'Heilige Drei Könige'; + private const NEUCHATEL_REPUBLIC_DAY = 'Neuenburger Republik tag'; + private const SAINT_JOSEPHS_DAY = 'Josefstag'; private const GOOD_FRIDAY = 'Karfreitag'; @@ -62,18 +68,28 @@ class Switzerland extends Country implements HasTranslations private const SWISS_NATIONAL_HOLIDAY = 'Bundesfeier'; + private const SWISS_NATIONAL_HOLIDAY_NEXT_DAY = 'Bundesfeier nächster tag'; + private const ASSUMPTION_DAY = 'Maria Himmelfahrt'; + private const GENEVA_DAY_OF_FASTING = 'Genfer Fasten'; + private const FEDERAL_DAY_OF_THANKSGIVING_REPENTANCE_AND_PRAYER = 'Buss- und Bettag'; + private const FEDERAL_DAY_OF_THANKSGIVING_REPENTANCE_AND_PRAYER_MONDAY = 'Buss- und Bettag Montag'; + private const ALL_SAINTS_DAY = 'Allerheiligen'; private const IMMACULATE_CONCEPTION = 'Maria Empfängnis'; private const CHRISTMAS_DAY = 'Weihnachtstag'; + private const CHRISTMAS_NEXT_DAY = 'Weihnachtsnächstertag'; + private const SAINT_STEPHENS_DAY = 'Stephanstag'; + private const GENEVA_REPUBLIC_DAY = 'Genf Republik tag'; + public function __construct(protected ?string $region = null) { if ($region !== null && ! in_array($region, self::REGIONS)) { @@ -110,19 +126,26 @@ public function regionalHolidays(int $year): array ]; $regionallyDifferentHolidays = [ + self::NEW_YEARS_NEXT_DAY => '01-02', self::BERCHTOLDS_DAY => '01-02', self::THREE_KINGS_DAY => '01-06', + self::NEUCHATEL_REPUBLIC_DAY => '03-01', self::SAINT_JOSEPHS_DAY => '03-19', self::GOOD_FRIDAY => $easter->subDays(2), self::EASTER_MONDAY => $easter->addDay(), self::LABOUR_DAY => '05-01', self::WHIT_MONDAY => $easter->addDays(50), self::CORPUS_CHRISTI => $easter->addDays(60), + self::SWISS_NATIONAL_HOLIDAY_NEXT_DAY => '08-02', self::ASSUMPTION_DAY => '08-15', + self::GENEVA_DAY_OF_FASTING => (new CarbonImmutable('first sunday of September '.$year, 'Europe/Zurich'))->addDays(4), // Thursday after the first Sunday of September self::FEDERAL_DAY_OF_THANKSGIVING_REPENTANCE_AND_PRAYER => new CarbonImmutable('third sunday of September '.$year, 'Europe/Zurich'), + self::FEDERAL_DAY_OF_THANKSGIVING_REPENTANCE_AND_PRAYER_MONDAY => (new CarbonImmutable('third sunday of September '.$year, 'Europe/Zurich'))->addDay(), self::ALL_SAINTS_DAY => '11-01', self::IMMACULATE_CONCEPTION => '12-08', self::SAINT_STEPHENS_DAY => '12-26', + self::CHRISTMAS_NEXT_DAY => '12-26', + self::GENEVA_REPUBLIC_DAY => '12-31', ]; $currentRegion = match ($this->region) { @@ -163,13 +186,26 @@ public function regionalHolidays(int $year): array self::WHIT_MONDAY, self::SAINT_STEPHENS_DAY, ], - 'ch-fr' => [ + 'ch-fr', 'ch-fr-c' => [ // Catholic part of the canton is the default + self::GOOD_FRIDAY, + self::CORPUS_CHRISTI, + self::ASSUMPTION_DAY, + self::ALL_SAINTS_DAY, + self::IMMACULATE_CONCEPTION, + ], + 'ch-fr-r' => [ // Reformed part of the canton has special legislation for holidays + self::NEW_YEARS_NEXT_DAY, self::GOOD_FRIDAY, + self::EASTER_MONDAY, + self::WHIT_MONDAY, + self::SAINT_STEPHENS_DAY, ], 'ch-ge' => [ self::GOOD_FRIDAY, self::EASTER_MONDAY, self::WHIT_MONDAY, + self::GENEVA_DAY_OF_FASTING, + self::GENEVA_REPUBLIC_DAY, ], 'ch-gl' => [ self::GOOD_FRIDAY, @@ -198,6 +234,7 @@ public function regionalHolidays(int $year): array self::SAINT_STEPHENS_DAY, ], 'ch-ne' => [ + self::NEUCHATEL_REPUBLIC_DAY, self::GOOD_FRIDAY, self::LABOUR_DAY, ], @@ -269,6 +306,7 @@ public function regionalHolidays(int $year): array self::GOOD_FRIDAY, self::EASTER_MONDAY, self::WHIT_MONDAY, + self::FEDERAL_DAY_OF_THANKSGIVING_REPENTANCE_AND_PRAYER_MONDAY, ], 'ch-vs' => [ self::SAINT_JOSEPHS_DAY, @@ -301,6 +339,22 @@ public function regionalHolidays(int $year): array ARRAY_FILTER_USE_KEY ); + // Some holidays only happen in some years in some regions + if (in_array($this->region, ['ch-ge', 'ch-ne']) && + (new CarbonImmutable("{$year}-01-01", 'Europe/Zurich'))->isSunday()) { + $regionalHolidays[self::NEW_YEARS_NEXT_DAY] = '01-02'; + } + + if (in_array($this->region, ['ch-ge']) && + (new CarbonImmutable("{$year}-08-01", 'Europe/Zurich'))->isSunday()) { + $regionalHolidays[self::SWISS_NATIONAL_HOLIDAY_NEXT_DAY] = '08-02'; + } + + if (in_array($this->region, ['ch-ge', 'ch-ne']) && + (new CarbonImmutable("{$year}-12-25", 'Europe/Zurich'))->isSunday()) { + $regionalHolidays[self::CHRISTMAS_NEXT_DAY] = '12-26'; + } + return array_merge($regionalHolidays, $sharedHolidays); } From 3f2f02537e109a464525256b02dffd9462ae20b8 Mon Sep 17 00:00:00 2001 From: Nielsvanpach Date: Tue, 2 Apr 2024 15:23:40 +0000 Subject: [PATCH 2/2] Update CHANGELOG --- CHANGELOG.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index cecec3255..1bb841704 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,20 @@ All notable changes to `holidays` will be documented in this file. +## 1.9.1 - 2024-04-02 + +### What's Changed + +* Bump dependabot/fetch-metadata from 1.6.0 to 2.0.0 by @dependabot in https://github.com/spatie/holidays/pull/215 +* Fix the Holidays in French speaking Switzerland by @OlinB in https://github.com/spatie/holidays/pull/217 + +### New Contributors + +* @dependabot made their first contribution in https://github.com/spatie/holidays/pull/215 +* @OlinB made their first contribution in https://github.com/spatie/holidays/pull/217 + +**Full Changelog**: https://github.com/spatie/holidays/compare/1.9.0...1.9.1 + ## 1.9.0 - 2024-03-22 ### What's Changed