Skip to content

Commit

Permalink
Draft: Add Support for Switzerland (#49)
Browse files Browse the repository at this point in the history
* feat: add switzerland

* test: add switzerland test

* feat: add region and translation Support

* test: update tests

* test: add snapshots

* feat: add translations for switzerland

* feat: update switzerland to use global languages

* test: update Switzerland tests
  • Loading branch information
Martin-Welte authored Jan 27, 2024
1 parent a3d0e1f commit 4c5ff96
Show file tree
Hide file tree
Showing 10 changed files with 598 additions and 0 deletions.
18 changes: 18 additions & 0 deletions lang/switzerland/de/holidays.json
Original file line number Diff line number Diff line change
@@ -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"
}
18 changes: 18 additions & 0 deletions lang/switzerland/fr/holidays.json
Original file line number Diff line number Diff line change
@@ -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"
}
18 changes: 18 additions & 0 deletions lang/switzerland/it/holidays.json
Original file line number Diff line number Diff line change
@@ -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"
}
316 changes: 316 additions & 0 deletions src/Countries/Switzerland.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,316 @@
<?php

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 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)
{
if ($region !== null && !in_array($region, self::REGIONS)) {
throw InvalidRegion::unsupportedRegion($region);
}
}

public function countryCode(): string
{
return 'ch';
}

/**
* @return array<string, CarbonImmutable|string>
*/
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',
];

$currentRegion = match($this->region) {
'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,
],
default => [],
};

$regionalHolidays = array_filter(
$regionallyDifferentHolidays,
fn ($key) => in_array($key, $currentRegion),
ARRAY_FILTER_USE_KEY
);

return array_merge($regionalHolidays, $sharedHolidays);
}

protected function allHolidays(int $year): array
{
if($this->region !== null) {
return $this->regionalHolidays($year);
}

return array_merge([
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));
}

/** @return array<string, CarbonImmutable> */
protected function variableHolidays(int $year): array
{
$easter = $this->easter($year);

return [
self::GOOD_FRIDAY => $easter->subDays(2),
self::EASTER_MONDAY => $easter->addDay(),
self::ASCENSION_DAY => $easter->addDays(39),
self::WHIT_MONDAY => $easter->addDays(50),
];
}
}
18 changes: 18 additions & 0 deletions src/Exceptions/InvalidRegion.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

namespace Spatie\Holidays\Exceptions;

use RuntimeException;

class InvalidRegion extends RuntimeException
{
public static function unsupportedRegion(string $region): self
{
return new self("Region '$region' is not supported.");
}

public static function unsupportedLocale(string $locale): self
{
return new self("Locale '$locale' is not supported.");
}
}
Loading

0 comments on commit 4c5ff96

Please sign in to comment.