From dd66d6fcfe0ae28bfd2e6398eb557b552a7efbf2 Mon Sep 17 00:00:00 2001 From: Martin Welte Date: Sat, 27 Jan 2024 12:47:40 +0100 Subject: [PATCH 1/8] feat: add switzerland --- src/Countries/Switzerland.php | 37 +++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 src/Countries/Switzerland.php diff --git a/src/Countries/Switzerland.php b/src/Countries/Switzerland.php new file mode 100644 index 000000000..38c0d62b4 --- /dev/null +++ b/src/Countries/Switzerland.php @@ -0,0 +1,37 @@ + '01-01', + 'Berchtoldstag' => '01-02', + 'Bundesfeier' => '08-01', + 'Weihnachtstag' => '12-25', + 'Stephanstag' => '12-26', + ], $this->variableHolidays($year)); + } + + /** @return array */ + protected function variableHolidays(int $year): array + { + $easter = $this->easter($year); + + return [ + 'Karfreitag' => $easter->subDays(2), + 'Ostermontag' => $easter->addDay(), + 'Auffahrt' => $easter->addDays(39), + 'Pfingstmontag' => $easter->addDays(50), + ]; + } +} From 8ec81ebbbb5f6679731a121c1499f4dd2fd0a461 Mon Sep 17 00:00:00 2001 From: Martin Welte Date: Sat, 27 Jan 2024 12:47:40 +0100 Subject: [PATCH 2/8] test: add switzerland test --- .../it_can_calculate_swiss_holidays.snap | 38 +++++++++++++++++++ tests/Countries/SwitzerlandTest.php | 18 +++++++++ 2 files changed, 56 insertions(+) create mode 100644 tests/.pest/snapshots/Countries/SwitzerlandTest/it_can_calculate_swiss_holidays.snap create mode 100644 tests/Countries/SwitzerlandTest.php diff --git a/tests/.pest/snapshots/Countries/SwitzerlandTest/it_can_calculate_swiss_holidays.snap b/tests/.pest/snapshots/Countries/SwitzerlandTest/it_can_calculate_swiss_holidays.snap new file mode 100644 index 000000000..96cd86c9b --- /dev/null +++ b/tests/.pest/snapshots/Countries/SwitzerlandTest/it_can_calculate_swiss_holidays.snap @@ -0,0 +1,38 @@ +[ + { + "name": "Neujahr", + "date": "2024-01-01" + }, + { + "name": "Berchtoldstag", + "date": "2024-01-02" + }, + { + "name": "Karfreitag", + "date": "2024-03-29" + }, + { + "name": "Ostermontag", + "date": "2024-04-01" + }, + { + "name": "Auffahrt", + "date": "2024-05-09" + }, + { + "name": "Pfingstmontag", + "date": "2024-05-20" + }, + { + "name": "Bundesfeier", + "date": "2024-08-01" + }, + { + "name": "Weihnachtstag", + "date": "2024-12-25" + }, + { + "name": "Stephanstag", + "date": "2024-12-26" + } +] \ No newline at end of file diff --git a/tests/Countries/SwitzerlandTest.php b/tests/Countries/SwitzerlandTest.php new file mode 100644 index 000000000..dff2a2fd1 --- /dev/null +++ b/tests/Countries/SwitzerlandTest.php @@ -0,0 +1,18 @@ +get(); + + expect($holidays) + ->toBeArray() + ->not()->toBeEmpty(); + + expect(formatDates($holidays))->toMatchSnapshot(); +}); From 9916c7cd11ac3d150a887c219825af481aa10b24 Mon Sep 17 00:00:00 2001 From: Martin Welte Date: Sat, 27 Jan 2024 12:47:40 +0100 Subject: [PATCH 3/8] feat: add region and translation Support --- src/Countries/Switzerland.php | 411 ++++++++++++++++++++++++++++++- src/Exceptions/InvalidRegion.php | 18 ++ 2 files changed, 419 insertions(+), 10 deletions(-) create mode 100644 src/Exceptions/InvalidRegion.php diff --git a/src/Countries/Switzerland.php b/src/Countries/Switzerland.php index 38c0d62b4..a787f562b 100644 --- a/src/Countries/Switzerland.php +++ b/src/Countries/Switzerland.php @@ -3,35 +3,426 @@ namespace Spatie\Holidays\Countries; use Carbon\CarbonImmutable; +use Spatie\Holidays\Exceptions\InvalidRegion; class Switzerland extends Country { + private const REGIONS = [ + 'ch-ag', + 'ch-ar', + 'ch-ai', + 'ch-bl', + 'ch-bs', + 'ch-be', + 'ch-fr', + 'ch-ge', + 'ch-gl', + 'ch-gr', + 'ch-ju', + 'ch-lu', + 'ch-ne', + 'ch-nw', + 'ch-ow', + 'ch-sh', + 'ch-sz', + 'ch-so', + 'ch-sg', + 'ch-ti', + 'ch-tg', + 'ch-ur', + 'ch-vd', + 'ch-vs', + 'ch-zg', + 'ch-zh', + ]; + + private const LOCALES = [ + 'de', + 'fr', + 'it', + ]; + + private const NEW_YEAR = 'Neujahr'; + + private const SECOND_JANUARY = 'Berchtoldstag'; + + private const THREE_KINGS = 'Heilige Drei Könige'; + + private const DAY_OF_JOSEPH = 'Josefstag'; + + private const GOOD_FRIDAY = 'Karfreitag'; + + private const EASTER_MONDAY = 'Ostermontag'; + + private const LABOR_DAY = 'Tag der Arbeit'; + + private const ASCENSION_DAY = 'Auffahrt'; + + private const WHIT_MONDAY = 'Pfingstmontag'; + + private const CORPUS_CHRISTI = 'Fronleichnam'; + + private const FEDERAL_CELEBRATION = 'Bundesfeier'; + + private const ASSUMPTION_DAY = 'Maria Himmelfahrt'; + + private const ALL_SAINTS_DAY = 'Allerheiligen'; + + private const IMMACULATE_CONCEPTION = 'Maria Empfängnis'; + + private const CHRISTMAS_DAY = 'Weihnachtstag'; + + private const ST_STEPHENS_DAY = 'Stephanstag'; + + public function __construct(protected ?string $region = null, protected ?string $locale = null) + { + if ($region !== null && !in_array($region, self::REGIONS)) { + throw InvalidRegion::unsupportedRegion($region); + } + + if($locale !== null && !in_array($locale, self::LOCALES)) { + throw InvalidRegion::unsupportedLocale($locale); + } + } + public function countryCode(): string { return 'ch'; } - protected function allHolidays(int $year): array + /** + * @return array + */ + public function regionalHolidays(int $year): array + { + if ($this->region === null) { + return []; + } + + $easter = $this->easter($year); + + $sharedHolidays = [ + self::NEW_YEAR => '01-01', + self::ASCENSION_DAY => $easter->addDays(39), + self::FEDERAL_CELEBRATION => '08-01', + self::CHRISTMAS_DAY => '12-25', + ]; + + $regionallyDifferentHolidays = [ + self::SECOND_JANUARY => '01-02', + self::THREE_KINGS => '01-06', + self::DAY_OF_JOSEPH => '03-19', + self::GOOD_FRIDAY => $easter->subDays(2), + self::EASTER_MONDAY => $easter->addDay(), + self::LABOR_DAY => '05-01', + self::WHIT_MONDAY => $easter->addDays(50), + self::CORPUS_CHRISTI => $easter->addDays(60), + self::ASSUMPTION_DAY => '08-15', + self::ALL_SAINTS_DAY => '11-01', + self::IMMACULATE_CONCEPTION => '12-08', + self::ST_STEPHENS_DAY => '12-26', + ]; + + $regions = [ + 'ch-ag' => [ + self::GOOD_FRIDAY, + ], + 'ch-ar' => [ + self::GOOD_FRIDAY, + self::EASTER_MONDAY, + self::WHIT_MONDAY, + self::ST_STEPHENS_DAY, + ], + 'ch-ai' => [ + self::GOOD_FRIDAY, + self::EASTER_MONDAY, + self::WHIT_MONDAY, + self::CORPUS_CHRISTI, + self::ST_STEPHENS_DAY, + ], + 'ch-bl' => [ + self::GOOD_FRIDAY, + self::EASTER_MONDAY, + self::LABOR_DAY, + self::WHIT_MONDAY, + self::ST_STEPHENS_DAY, + ], + 'ch-bs' => [ + self::GOOD_FRIDAY, + self::EASTER_MONDAY, + self::LABOR_DAY, + self::WHIT_MONDAY, + self::ST_STEPHENS_DAY, + ], + 'ch-be' => [ + self::SECOND_JANUARY, + self::GOOD_FRIDAY, + self::EASTER_MONDAY, + self::WHIT_MONDAY, + self::ST_STEPHENS_DAY, + ], + 'ch-fr' => [ + self::GOOD_FRIDAY, + ], + 'ch-ge' => [ + self::GOOD_FRIDAY, + self::EASTER_MONDAY, + self::WHIT_MONDAY, + ], + 'ch-gl' => [ + self::GOOD_FRIDAY, + self::EASTER_MONDAY, + self::ALL_SAINTS_DAY, + self::IMMACULATE_CONCEPTION, + ], + 'ch-gr' => [ + self::GOOD_FRIDAY, + self::EASTER_MONDAY, + self::WHIT_MONDAY, + self::ST_STEPHENS_DAY, + ], + 'ch-ju' => [ + self::GOOD_FRIDAY, + self::EASTER_MONDAY, + self::LABOR_DAY, + self::WHIT_MONDAY, + self::CORPUS_CHRISTI, + ], + 'ch-lu' => [ + self::GOOD_FRIDAY, + self::CORPUS_CHRISTI, + self::ASSUMPTION_DAY, + self::ALL_SAINTS_DAY, + self::ST_STEPHENS_DAY, + ], + 'ch-ne' => [ + self::GOOD_FRIDAY, + self::LABOR_DAY, + ], + 'ch-nw' => [ + self::GOOD_FRIDAY, + self::CORPUS_CHRISTI, + self::ASSUMPTION_DAY, + self::ALL_SAINTS_DAY, + self::IMMACULATE_CONCEPTION, + ], + 'ch-ow' => [ + self::GOOD_FRIDAY, + self::CORPUS_CHRISTI, + self::ASSUMPTION_DAY, + self::ALL_SAINTS_DAY, + self::IMMACULATE_CONCEPTION, + ], + 'ch-sh' => [ + self::GOOD_FRIDAY, + self::EASTER_MONDAY, + self::WHIT_MONDAY, + self::ST_STEPHENS_DAY, + ], + 'ch-sz' => [ + self::DAY_OF_JOSEPH, + self::GOOD_FRIDAY, + self::CORPUS_CHRISTI, + self::ASSUMPTION_DAY, + self::ALL_SAINTS_DAY, + ], + 'ch-so' => [ + self::GOOD_FRIDAY, + ], + 'ch-sg' => [ + self::GOOD_FRIDAY, + self::EASTER_MONDAY, + self::WHIT_MONDAY, + self::ALL_SAINTS_DAY, + self::ST_STEPHENS_DAY, + ], + 'ch-ti' => [ + self::THREE_KINGS, + self::EASTER_MONDAY, + self::ASSUMPTION_DAY, + self::ALL_SAINTS_DAY, + self::ST_STEPHENS_DAY, + ], + 'ch-tg' => [ + self::SECOND_JANUARY, + self::GOOD_FRIDAY, + self::EASTER_MONDAY, + self::WHIT_MONDAY, + self::ST_STEPHENS_DAY, + ], + 'ch-ur' => [ + self::GOOD_FRIDAY, + self::CORPUS_CHRISTI, + self::ASSUMPTION_DAY, + self::ALL_SAINTS_DAY, + self::IMMACULATE_CONCEPTION, + ], + 'ch-vd' => [ + self::SECOND_JANUARY, + self::GOOD_FRIDAY, + self::EASTER_MONDAY, + self::WHIT_MONDAY, + ], + 'ch-vs' => [ + self::DAY_OF_JOSEPH, + self::CORPUS_CHRISTI, + self::ASSUMPTION_DAY, + self::ALL_SAINTS_DAY, + self::IMMACULATE_CONCEPTION, + ], + 'ch-zg' => [ + self::GOOD_FRIDAY, + self::CORPUS_CHRISTI, + self::ASSUMPTION_DAY, + self::ALL_SAINTS_DAY, + self::IMMACULATE_CONCEPTION, + ], + 'ch-zh' => [ + self::GOOD_FRIDAY, + self::EASTER_MONDAY, + self::LABOR_DAY, + self::WHIT_MONDAY, + self::ST_STEPHENS_DAY, + ], + ]; + + $currentRegion = $regions[$this->region]; + + $regionalHolidays = array_filter( + $regionallyDifferentHolidays, + fn ($key) => in_array($key, $currentRegion), + ARRAY_FILTER_USE_KEY + ); + + return array_merge($regionalHolidays, $sharedHolidays); + } + + /** + * @param array $holidays + * @return array + */ + protected function translateHolidays(array $holidays): array + { + if ($this->locale === null) { + return $holidays; + } + + $translatedHolidays = []; + + foreach ($holidays as $name => $date) { + /** @var string $translatedName */ + $translatedName = $this->translate($name); + $translatedHolidays[$translatedName] = $date; + } + + return $translatedHolidays; + } + + protected function translate(string $name): string + { + $translations = [ + 'de' => [ + self::NEW_YEAR => 'Neujahr', + self::SECOND_JANUARY => 'Berchtoldstag', + self::THREE_KINGS => 'Heilige Drei Könige', + self::DAY_OF_JOSEPH => 'Josefstag', + self::GOOD_FRIDAY => 'Karfreitag', + self::EASTER_MONDAY => 'Ostermontag', + self::LABOR_DAY => 'Tag der Arbeit', + self::ASCENSION_DAY => 'Auffahrt', + self::WHIT_MONDAY => 'Pfingstmontag', + self::CORPUS_CHRISTI => 'Fronleichnam', + self::FEDERAL_CELEBRATION => 'Bundesfeier', + self::ASSUMPTION_DAY => 'Maria Himmelfahrt', + self::ALL_SAINTS_DAY => 'Allerheiligen', + self::IMMACULATE_CONCEPTION => 'Maria Empfängnis', + self::CHRISTMAS_DAY => 'Weihnachtstag', + self::ST_STEPHENS_DAY => 'Stephanstag', + ], + 'fr' => [ + self::NEW_YEAR => 'Nouvel An', + self::SECOND_JANUARY => 'Saint-Berthold', + self::THREE_KINGS => 'Épiphanie', + self::DAY_OF_JOSEPH => 'Saint-Joseph', + self::GOOD_FRIDAY => 'Vendredi saint', + self::EASTER_MONDAY => 'Lundi de Pâques', + self::LABOR_DAY => 'Fête du travail', + self::ASCENSION_DAY => 'Ascension', + self::WHIT_MONDAY => 'Lundi de Pentecôte', + self::CORPUS_CHRISTI => 'Fête-Dieu', + self::FEDERAL_CELEBRATION => 'Fête nationale', + self::ASSUMPTION_DAY => 'Assomption', + self::ALL_SAINTS_DAY => 'Toussaint', + self::IMMACULATE_CONCEPTION => 'Immaculée Conception', + self::CHRISTMAS_DAY => 'Noël', + self::ST_STEPHENS_DAY => 'Saint-Étienne', + ], + 'it' => [ + self::NEW_YEAR => 'Capodanno', + self::SECOND_JANUARY => 'San Silvestro', + self::THREE_KINGS => 'Epifania', + self::DAY_OF_JOSEPH => 'San Giuseppe', + self::GOOD_FRIDAY => 'Venerdì Santo', + self::EASTER_MONDAY => 'Lunedì di Pasqua', + self::LABOR_DAY => 'Festa del lavoro', + self::ASCENSION_DAY => 'Ascensione', + self::WHIT_MONDAY => 'Lunedì di Pentecoste', + self::CORPUS_CHRISTI => 'Corpus Domini', + self::FEDERAL_CELEBRATION => 'Festa nazionale', + self::ASSUMPTION_DAY => 'Assunzione', + self::ALL_SAINTS_DAY => 'Ognissanti', + self::IMMACULATE_CONCEPTION => 'Immacolata Concezione', + self::CHRISTMAS_DAY => 'Natale', + self::ST_STEPHENS_DAY => 'Santo Stefano', + ], + ]; + + return $translations[$this->locale][$name]; + } + + /** + * @return array + */ + protected function translatedHolidays(int $year): array + { + return $this->translateHolidays($this->untranslatedHolidays($year)); + } + + /** + * @return array + */ + protected function untranslatedHolidays(int $year): array { + if($this->region !== null) { + return $this->regionalHolidays($year); + } + return array_merge([ - 'Neujahr' => '01-01', - 'Berchtoldstag' => '01-02', - 'Bundesfeier' => '08-01', - 'Weihnachtstag' => '12-25', - 'Stephanstag' => '12-26', + self::NEW_YEAR => '01-01', + self::SECOND_JANUARY => '01-02', + self::FEDERAL_CELEBRATION => '08-01', + self::CHRISTMAS_DAY => '12-25', + self::ST_STEPHENS_DAY => '12-26', ], $this->variableHolidays($year)); } + protected function allHolidays(int $year): array + { + return $this->locale !== null + ? $this->translatedHolidays($year) + : $this->untranslatedHolidays($year); + } + /** @return array */ protected function variableHolidays(int $year): array { $easter = $this->easter($year); return [ - 'Karfreitag' => $easter->subDays(2), - 'Ostermontag' => $easter->addDay(), - 'Auffahrt' => $easter->addDays(39), - 'Pfingstmontag' => $easter->addDays(50), + self::GOOD_FRIDAY => $easter->subDays(2), + self::EASTER_MONDAY => $easter->addDay(), + self::ASCENSION_DAY => $easter->addDays(39), + self::WHIT_MONDAY => $easter->addDays(50), ]; } } diff --git a/src/Exceptions/InvalidRegion.php b/src/Exceptions/InvalidRegion.php new file mode 100644 index 000000000..7941fe2b5 --- /dev/null +++ b/src/Exceptions/InvalidRegion.php @@ -0,0 +1,18 @@ + Date: Sat, 27 Jan 2024 12:47:40 +0100 Subject: [PATCH 4/8] test: update tests --- tests/Countries/SwitzerlandTest.php | 38 +++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/tests/Countries/SwitzerlandTest.php b/tests/Countries/SwitzerlandTest.php index dff2a2fd1..dabb75433 100644 --- a/tests/Countries/SwitzerlandTest.php +++ b/tests/Countries/SwitzerlandTest.php @@ -3,6 +3,8 @@ namespace Spatie\Holidays\Tests\Countries; use Carbon\CarbonImmutable; +use Spatie\Holidays\Countries\Switzerland; +use Spatie\Holidays\Exceptions\InvalidRegion; use Spatie\Holidays\Holidays; it('can calculate swiss holidays', function () { @@ -16,3 +18,39 @@ expect(formatDates($holidays))->toMatchSnapshot(); }); + +it('can get swiss holidays for a specified region (zh)', function() { + CarbonImmutable::setTestNowAndTimezone('2024-01-01'); + + $switzerland = new Switzerland(region: 'ch-zh'); + + $holidays = Holidays::for($switzerland)->get(); + + expect($holidays) + ->toBeArray() + ->not()->toBeEmpty(); + + expect(formatDates($holidays))->toMatchSnapshot(); +}); + +it('throws an error when an invalid region is given', function () { + new Switzerland('ch-xx'); +})->throws(InvalidRegion::class); + +it('can translate swiss holidays', function() { + CarbonImmutable::setTestNowAndTimezone('2024-01-01'); + + $switzerland = new Switzerland(locale: 'fr'); + + $holidays = Holidays::for($switzerland)->get(); + + expect($holidays) + ->toBeArray() + ->not()->toBeEmpty(); + + expect(formatDates($holidays))->toMatchSnapshot(); +}); + +it('throws an error when an invalid locale is given', function () { + new Switzerland(locale: 'xx'); +})->throws(InvalidRegion::class); From da09106d5d9c2e515c25387f1e67ba68a4135099 Mon Sep 17 00:00:00 2001 From: Martin Welte Date: Sat, 27 Jan 2024 12:47:40 +0100 Subject: [PATCH 5/8] test: add snapshots --- ..._holidays_for_a_specified_region__zh_.snap | 38 +++++++++++++++++++ .../it_can_translate_swiss_holidays.snap | 38 +++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 tests/.pest/snapshots/Countries/SwitzerlandTest/it_can_get_swiss_holidays_for_a_specified_region__zh_.snap create mode 100644 tests/.pest/snapshots/Countries/SwitzerlandTest/it_can_translate_swiss_holidays.snap diff --git a/tests/.pest/snapshots/Countries/SwitzerlandTest/it_can_get_swiss_holidays_for_a_specified_region__zh_.snap b/tests/.pest/snapshots/Countries/SwitzerlandTest/it_can_get_swiss_holidays_for_a_specified_region__zh_.snap new file mode 100644 index 000000000..f4b753733 --- /dev/null +++ b/tests/.pest/snapshots/Countries/SwitzerlandTest/it_can_get_swiss_holidays_for_a_specified_region__zh_.snap @@ -0,0 +1,38 @@ +[ + { + "name": "Neujahr", + "date": "2024-01-01" + }, + { + "name": "Karfreitag", + "date": "2024-03-29" + }, + { + "name": "Ostermontag", + "date": "2024-04-01" + }, + { + "name": "Tag der Arbeit", + "date": "2024-05-01" + }, + { + "name": "Auffahrt", + "date": "2024-05-09" + }, + { + "name": "Pfingstmontag", + "date": "2024-05-20" + }, + { + "name": "Bundesfeier", + "date": "2024-08-01" + }, + { + "name": "Weihnachtstag", + "date": "2024-12-25" + }, + { + "name": "Stephanstag", + "date": "2024-12-26" + } +] \ No newline at end of file diff --git a/tests/.pest/snapshots/Countries/SwitzerlandTest/it_can_translate_swiss_holidays.snap b/tests/.pest/snapshots/Countries/SwitzerlandTest/it_can_translate_swiss_holidays.snap new file mode 100644 index 000000000..5cb53af4e --- /dev/null +++ b/tests/.pest/snapshots/Countries/SwitzerlandTest/it_can_translate_swiss_holidays.snap @@ -0,0 +1,38 @@ +[ + { + "name": "Nouvel An", + "date": "2024-01-01" + }, + { + "name": "Saint-Berthold", + "date": "2024-01-02" + }, + { + "name": "Vendredi saint", + "date": "2024-03-29" + }, + { + "name": "Lundi de P\u00e2ques", + "date": "2024-04-01" + }, + { + "name": "Ascension", + "date": "2024-05-09" + }, + { + "name": "Lundi de Pentec\u00f4te", + "date": "2024-05-20" + }, + { + "name": "F\u00eate nationale", + "date": "2024-08-01" + }, + { + "name": "No\u00ebl", + "date": "2024-12-25" + }, + { + "name": "Saint-\u00c9tienne", + "date": "2024-12-26" + } +] \ No newline at end of file From fd53e7f5f0cf7f8522b1d94e0d9df56da345b90a Mon Sep 17 00:00:00 2001 From: Martin Welte Date: Sat, 27 Jan 2024 15:52:35 +0100 Subject: [PATCH 6/8] feat: add translations for switzerland --- lang/switzerland/de/holidays.json | 18 ++++++++++++++++++ lang/switzerland/fr/holidays.json | 18 ++++++++++++++++++ lang/switzerland/it/holidays.json | 18 ++++++++++++++++++ 3 files changed, 54 insertions(+) create mode 100644 lang/switzerland/de/holidays.json create mode 100644 lang/switzerland/fr/holidays.json create mode 100644 lang/switzerland/it/holidays.json diff --git a/lang/switzerland/de/holidays.json b/lang/switzerland/de/holidays.json new file mode 100644 index 000000000..c294fd7b8 --- /dev/null +++ b/lang/switzerland/de/holidays.json @@ -0,0 +1,18 @@ +{ + "Neujahr": "Neujahr", + "Berchtoldstag": "Berchtoldstag", + "Heilige Drei Könige": "Heilige Drei Könige", + "Josefstag": "Josefstag", + "Karfreitag": "Karfreitag", + "Ostermontag": "Ostermontag", + "Tag der Arbeit": "Tag der Arbeit", + "Auffahrt": "Auffahrt", + "Pfingstmontag": "Pfingstmontag", + "Fronleichnam": "Fronleichnam", + "Bundesfeier": "Bundesfeier", + "Maria Himmelfahrt": "Maria Himmelfahrt", + "Allerheiligen": "Allerheiligen", + "Maria Empfängnis": "Maria Empfängnis", + "Weihnachtstag": "Weihnachtstag", + "Stephanstag": "Stephanstag" +} diff --git a/lang/switzerland/fr/holidays.json b/lang/switzerland/fr/holidays.json new file mode 100644 index 000000000..0fe65215c --- /dev/null +++ b/lang/switzerland/fr/holidays.json @@ -0,0 +1,18 @@ +{ + "Neujahr": "Nouvel An", + "Berchtoldstag": "Saint-Berthold", + "Heilige Drei Könige": "Épiphanie", + "Josefstag": "Saint-Joseph", + "Karfreitag": "Vendredi saint", + "Ostermontag": "Lundi de Pâques", + "Tag der Arbeit": "Fête du travail", + "Auffahrt": "Ascension", + "Pfingstmontag": "Lundi de Pentecôte", + "Fronleichnam": "Fête-Dieu", + "Bundesfeier": "Fête nationale", + "Maria Himmelfahrt": "Assomption", + "Allerheiligen": "Toussaint", + "Maria Empfängnis": "Immaculée Conception", + "Weihnachtstag": "Noël", + "Stephanstag": "Saint-Étienne" +} diff --git a/lang/switzerland/it/holidays.json b/lang/switzerland/it/holidays.json new file mode 100644 index 000000000..e7a30514c --- /dev/null +++ b/lang/switzerland/it/holidays.json @@ -0,0 +1,18 @@ +{ + "Neujahr": "Capodanno", + "Berchtoldstag": "San Silvestro", + "Heilige Drei Könige": "Epifania", + "Josefstag": "San Giuseppe", + "Karfreitag": "Venerdì Santo", + "Ostermontag": "Lunedì di Pasqua", + "Tag der Arbeit": "Festa del lavoro", + "Auffahrt": "Ascensione", + "Pfingstmontag": "Lunedì di Pentecoste", + "Fronleichnam": "Corpus Domini", + "Bundesfeier": "Festa nazionale", + "Maria Himmelfahrt": "Assunzione", + "Allerheiligen": "Ognissanti", + "Maria Empfängnis": "Immacolata Concezione", + "Weihnachtstag": "Natale", + "Stephanstag": "Santo Stefano" +} From f3e527dbc74899173e2a00befb283bde0431f78c Mon Sep 17 00:00:00 2001 From: Martin Welte Date: Sat, 27 Jan 2024 15:52:58 +0100 Subject: [PATCH 7/8] feat: update switzerland to use global languages --- src/Countries/Switzerland.php | 122 ++-------------------------------- 1 file changed, 5 insertions(+), 117 deletions(-) diff --git a/src/Countries/Switzerland.php b/src/Countries/Switzerland.php index a787f562b..6259e3d9b 100644 --- a/src/Countries/Switzerland.php +++ b/src/Countries/Switzerland.php @@ -36,12 +36,6 @@ class Switzerland extends Country 'ch-zh', ]; - private const LOCALES = [ - 'de', - 'fr', - 'it', - ]; - private const NEW_YEAR = 'Neujahr'; private const SECOND_JANUARY = 'Berchtoldstag'; @@ -74,15 +68,11 @@ class Switzerland extends Country private const ST_STEPHENS_DAY = 'Stephanstag'; - public function __construct(protected ?string $region = null, protected ?string $locale = null) + public function __construct(protected ?string $region = null) { if ($region !== null && !in_array($region, self::REGIONS)) { throw InvalidRegion::unsupportedRegion($region); } - - if($locale !== null && !in_array($locale, self::LOCALES)) { - throw InvalidRegion::unsupportedLocale($locale); - } } public function countryCode(): string @@ -123,7 +113,7 @@ public function regionalHolidays(int $year): array self::ST_STEPHENS_DAY => '12-26', ]; - $regions = [ + $currentRegion = match($this->region) { 'ch-ag' => [ self::GOOD_FRIDAY, ], @@ -284,9 +274,8 @@ public function regionalHolidays(int $year): array self::WHIT_MONDAY, self::ST_STEPHENS_DAY, ], - ]; - - $currentRegion = $regions[$this->region]; + default => [], + }; $regionalHolidays = array_filter( $regionallyDifferentHolidays, @@ -297,101 +286,7 @@ public function regionalHolidays(int $year): array return array_merge($regionalHolidays, $sharedHolidays); } - /** - * @param array $holidays - * @return array - */ - protected function translateHolidays(array $holidays): array - { - if ($this->locale === null) { - return $holidays; - } - - $translatedHolidays = []; - - foreach ($holidays as $name => $date) { - /** @var string $translatedName */ - $translatedName = $this->translate($name); - $translatedHolidays[$translatedName] = $date; - } - - return $translatedHolidays; - } - - protected function translate(string $name): string - { - $translations = [ - 'de' => [ - self::NEW_YEAR => 'Neujahr', - self::SECOND_JANUARY => 'Berchtoldstag', - self::THREE_KINGS => 'Heilige Drei Könige', - self::DAY_OF_JOSEPH => 'Josefstag', - self::GOOD_FRIDAY => 'Karfreitag', - self::EASTER_MONDAY => 'Ostermontag', - self::LABOR_DAY => 'Tag der Arbeit', - self::ASCENSION_DAY => 'Auffahrt', - self::WHIT_MONDAY => 'Pfingstmontag', - self::CORPUS_CHRISTI => 'Fronleichnam', - self::FEDERAL_CELEBRATION => 'Bundesfeier', - self::ASSUMPTION_DAY => 'Maria Himmelfahrt', - self::ALL_SAINTS_DAY => 'Allerheiligen', - self::IMMACULATE_CONCEPTION => 'Maria Empfängnis', - self::CHRISTMAS_DAY => 'Weihnachtstag', - self::ST_STEPHENS_DAY => 'Stephanstag', - ], - 'fr' => [ - self::NEW_YEAR => 'Nouvel An', - self::SECOND_JANUARY => 'Saint-Berthold', - self::THREE_KINGS => 'Épiphanie', - self::DAY_OF_JOSEPH => 'Saint-Joseph', - self::GOOD_FRIDAY => 'Vendredi saint', - self::EASTER_MONDAY => 'Lundi de Pâques', - self::LABOR_DAY => 'Fête du travail', - self::ASCENSION_DAY => 'Ascension', - self::WHIT_MONDAY => 'Lundi de Pentecôte', - self::CORPUS_CHRISTI => 'Fête-Dieu', - self::FEDERAL_CELEBRATION => 'Fête nationale', - self::ASSUMPTION_DAY => 'Assomption', - self::ALL_SAINTS_DAY => 'Toussaint', - self::IMMACULATE_CONCEPTION => 'Immaculée Conception', - self::CHRISTMAS_DAY => 'Noël', - self::ST_STEPHENS_DAY => 'Saint-Étienne', - ], - 'it' => [ - self::NEW_YEAR => 'Capodanno', - self::SECOND_JANUARY => 'San Silvestro', - self::THREE_KINGS => 'Epifania', - self::DAY_OF_JOSEPH => 'San Giuseppe', - self::GOOD_FRIDAY => 'Venerdì Santo', - self::EASTER_MONDAY => 'Lunedì di Pasqua', - self::LABOR_DAY => 'Festa del lavoro', - self::ASCENSION_DAY => 'Ascensione', - self::WHIT_MONDAY => 'Lunedì di Pentecoste', - self::CORPUS_CHRISTI => 'Corpus Domini', - self::FEDERAL_CELEBRATION => 'Festa nazionale', - self::ASSUMPTION_DAY => 'Assunzione', - self::ALL_SAINTS_DAY => 'Ognissanti', - self::IMMACULATE_CONCEPTION => 'Immacolata Concezione', - self::CHRISTMAS_DAY => 'Natale', - self::ST_STEPHENS_DAY => 'Santo Stefano', - ], - ]; - - return $translations[$this->locale][$name]; - } - - /** - * @return array - */ - protected function translatedHolidays(int $year): array - { - return $this->translateHolidays($this->untranslatedHolidays($year)); - } - - /** - * @return array - */ - protected function untranslatedHolidays(int $year): array + protected function allHolidays(int $year): array { if($this->region !== null) { return $this->regionalHolidays($year); @@ -406,13 +301,6 @@ protected function untranslatedHolidays(int $year): array ], $this->variableHolidays($year)); } - protected function allHolidays(int $year): array - { - return $this->locale !== null - ? $this->translatedHolidays($year) - : $this->untranslatedHolidays($year); - } - /** @return array */ protected function variableHolidays(int $year): array { From b507f15897316ee852b02daa593dc6ac90b20ea6 Mon Sep 17 00:00:00 2001 From: Martin Welte Date: Sat, 27 Jan 2024 15:53:07 +0100 Subject: [PATCH 8/8] test: update Switzerland tests --- ...translate_swiss_holidays_into_french.snap} | 0 ...translate_swiss_holidays_into_italian.snap | 38 +++++++++++++++++++ tests/Countries/SwitzerlandTest.php | 18 +++++---- 3 files changed, 48 insertions(+), 8 deletions(-) rename tests/.pest/snapshots/Countries/SwitzerlandTest/{it_can_translate_swiss_holidays.snap => it_can_translate_swiss_holidays_into_french.snap} (100%) create mode 100644 tests/.pest/snapshots/Countries/SwitzerlandTest/it_can_translate_swiss_holidays_into_italian.snap diff --git a/tests/.pest/snapshots/Countries/SwitzerlandTest/it_can_translate_swiss_holidays.snap b/tests/.pest/snapshots/Countries/SwitzerlandTest/it_can_translate_swiss_holidays_into_french.snap similarity index 100% rename from tests/.pest/snapshots/Countries/SwitzerlandTest/it_can_translate_swiss_holidays.snap rename to tests/.pest/snapshots/Countries/SwitzerlandTest/it_can_translate_swiss_holidays_into_french.snap diff --git a/tests/.pest/snapshots/Countries/SwitzerlandTest/it_can_translate_swiss_holidays_into_italian.snap b/tests/.pest/snapshots/Countries/SwitzerlandTest/it_can_translate_swiss_holidays_into_italian.snap new file mode 100644 index 000000000..b40b5b698 --- /dev/null +++ b/tests/.pest/snapshots/Countries/SwitzerlandTest/it_can_translate_swiss_holidays_into_italian.snap @@ -0,0 +1,38 @@ +[ + { + "name": "Capodanno", + "date": "2024-01-01" + }, + { + "name": "San Silvestro", + "date": "2024-01-02" + }, + { + "name": "Venerd\u00ec Santo", + "date": "2024-03-29" + }, + { + "name": "Luned\u00ec di Pasqua", + "date": "2024-04-01" + }, + { + "name": "Ascensione", + "date": "2024-05-09" + }, + { + "name": "Luned\u00ec di Pentecoste", + "date": "2024-05-20" + }, + { + "name": "Festa nazionale", + "date": "2024-08-01" + }, + { + "name": "Natale", + "date": "2024-12-25" + }, + { + "name": "Santo Stefano", + "date": "2024-12-26" + } +] \ No newline at end of file diff --git a/tests/Countries/SwitzerlandTest.php b/tests/Countries/SwitzerlandTest.php index dabb75433..1b3ba626a 100644 --- a/tests/Countries/SwitzerlandTest.php +++ b/tests/Countries/SwitzerlandTest.php @@ -37,12 +37,18 @@ new Switzerland('ch-xx'); })->throws(InvalidRegion::class); -it('can translate swiss holidays', function() { - CarbonImmutable::setTestNowAndTimezone('2024-01-01'); +it('can translate swiss holidays into french', function() { + $holidays = Holidays::for(country: 'ch', locale: 'fr', year: 2024)->get(); - $switzerland = new Switzerland(locale: 'fr'); + expect($holidays) + ->toBeArray() + ->not()->toBeEmpty(); - $holidays = Holidays::for($switzerland)->get(); + expect(formatDates($holidays))->toMatchSnapshot(); +}); + +it('can translate swiss holidays into italian', function() { + $holidays = Holidays::for(country: 'ch', locale: 'it', year: 2024)->get(); expect($holidays) ->toBeArray() @@ -50,7 +56,3 @@ expect(formatDates($holidays))->toMatchSnapshot(); }); - -it('throws an error when an invalid locale is given', function () { - new Switzerland(locale: 'xx'); -})->throws(InvalidRegion::class);