From af336947c8806c375519ec9f115b4631f6f85696 Mon Sep 17 00:00:00 2001 From: Christian Schmidt Date: Thu, 5 Sep 2019 22:22:03 +0200 Subject: [PATCH] Swedish observance holidays --- CHANGELOG.md | 1 + src/Yasumi/Provider/Sweden.php | 94 ++++++++++++++++-- src/Yasumi/data/translations/allSaintsEve.php | 18 ++++ src/Yasumi/data/translations/epiphanyEve.php | 18 ++++ src/Yasumi/data/translations/newYearsEve.php | 1 + src/Yasumi/data/translations/stJohnsDay.php | 1 + src/Yasumi/data/translations/stJohnsEve.php | 18 ++++ src/Yasumi/data/translations/walpurgisEve.php | 17 ++++ tests/Sweden/AllSaintsEveTest.php | 95 +++++++++++++++++++ tests/Sweden/ChristmasEveTest.php | 2 +- tests/Sweden/EpiphanyEveTest.php | 77 +++++++++++++++ tests/Sweden/NewYearsEveTest.php | 77 +++++++++++++++ ...{stJohnsDayTest.php => StJohnsDayTest.php} | 2 +- tests/Sweden/StJohnsEveTest.php | 75 +++++++++++++++ tests/Sweden/SwedenTest.php | 10 +- tests/Sweden/WalpurgisEveTest.php | 77 +++++++++++++++ 16 files changed, 572 insertions(+), 11 deletions(-) create mode 100755 src/Yasumi/data/translations/allSaintsEve.php create mode 100644 src/Yasumi/data/translations/epiphanyEve.php create mode 100644 src/Yasumi/data/translations/stJohnsEve.php create mode 100755 src/Yasumi/data/translations/walpurgisEve.php create mode 100644 tests/Sweden/AllSaintsEveTest.php create mode 100644 tests/Sweden/EpiphanyEveTest.php create mode 100644 tests/Sweden/NewYearsEveTest.php rename tests/Sweden/{stJohnsDayTest.php => StJohnsDayTest.php} (97%) create mode 100644 tests/Sweden/StJohnsEveTest.php create mode 100644 tests/Sweden/WalpurgisEveTest.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b103756b..f22261486 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p - Translation for the Easter holiday for the 'fr_FR' locale [\#146](https://github.com/azuyalabs/yasumi/pull/146) ([pioc92](https://github.com/pioc92)) - Translation for the Pentecoste holiday for the 'fr_FR' locale [\#145](https://github.com/azuyalabs/yasumi/pull/145) ([pioc92](https://github.com/pioc92)) - Late Summer Bank Holiday in United Kingdom prior to 1965 [\#161](https://github.com/azuyalabs/yasumi/pull/161) ([c960657](https://github.com/c960657)) +- Observance holidays for Sweden [\#172](https://github.com/azuyalabs/yasumi/pull/172) ([c960657](https://github.com/c960657)) ### Changed - Replaced the standard 'InvalidArgumentException' when an invalid year or holiday provider are given by a new exception for each of these two situations separately ('InvalidYearException' and 'ProviderNotFoundException'). This allows you to better distinguish which exception may occur when instantiating the Yasumi class. [\#95](https://github.com/azuyalabs/yasumi/pull/95) ([qneyrat](https://github.com/qneyrat)) diff --git a/src/Yasumi/Provider/Sweden.php b/src/Yasumi/Provider/Sweden.php index 26275c672..a60223a98 100644 --- a/src/Yasumi/Provider/Sweden.php +++ b/src/Yasumi/Provider/Sweden.php @@ -12,6 +12,7 @@ namespace Yasumi\Provider; +use DateInterval; use DateTime; use DateTimeZone; use Yasumi\Holiday; @@ -47,21 +48,80 @@ public function initialize(): void // Add common Christian holidays (common in Sweden) $this->addHoliday($this->epiphany($this->year, $this->timezone, $this->locale)); + $this->calculateEpiphanyEve(); + $this->calculateWalpurgisEve(); $this->addHoliday($this->goodFriday($this->year, $this->timezone, $this->locale)); $this->addHoliday($this->easter($this->year, $this->timezone, $this->locale)); $this->addHoliday($this->easterMonday($this->year, $this->timezone, $this->locale)); $this->addHoliday($this->ascensionDay($this->year, $this->timezone, $this->locale)); $this->addHoliday($this->pentecost($this->year, $this->timezone, $this->locale)); - $this->calculateStJohnsDay(); // aka Midsummer's Day - $this->calculateAllSaintsDay(); - $this->addHoliday($this->christmasEve($this->year, $this->timezone, $this->locale, Holiday::TYPE_OFFICIAL)); + $this->calculateStJohnsHolidays(); // aka Midsummer + $this->calculateAllSaintsHolidays(); + $this->addHoliday($this->christmasEve($this->year, $this->timezone, $this->locale, Holiday::TYPE_OBSERVANCE)); $this->addHoliday($this->christmasDay($this->year, $this->timezone, $this->locale)); $this->addHoliday($this->secondChristmasDay($this->year, $this->timezone, $this->locale)); + $this->addHoliday($this->newYearsEve($this->year, $this->timezone, $this->locale, Holiday::TYPE_OBSERVANCE)); + // Calculate other holidays $this->calculateNationalDay(); } + /** + * Epiphany Eve. + * + * Epiphany is a Christian feast day that celebrates the revelation of God the Son as a human being in Jesus Christ. + * The traditional date for the feast is January 6. In Sweden the holiday is celebrated on the evening before, also + * known as Twelfth Night. + * + * Epiphany Eve is often treated with the afternoon off, but this varies depending on employer. + * + * @link https://en.wikipedia.org/wiki/Twelfth_Night_(holiday) + * + * @throws \Yasumi\Exception\InvalidDateException + * @throws \Yasumi\Exception\UnknownLocaleException + * @throws \InvalidArgumentException + * @throws \Exception + */ + public function calculateEpiphanyEve(): void + { + $this->addHoliday(new Holiday( + 'epiphanyEve', + [], + new DateTime("$this->year-1-5", new DateTimeZone($this->timezone)), + $this->locale, + Holiday::TYPE_OBSERVANCE + )); + } + + + /** + * Walpurgis Night. + * + * Walpurgis Night is the eve of the Christian feast day of Saint Walpurga, an 8th-century abbess in Francia. + * This feast commemorates the canonization of Saint Walpurga and the movement of her relics to Eichstätt, + * both of which occurred on 1 May 870 + * + * Walpurgis Night is often treated with the afternoon off, but this varies depending on employer. + * + * @link https://en.wikipedia.org/wiki/Walpurgis_Night + * + * @throws \Yasumi\Exception\InvalidDateException + * @throws \Yasumi\Exception\UnknownLocaleException + * @throws \InvalidArgumentException + * @throws \Exception + */ + public function calculateWalpurgisEve(): void + { + $this->addHoliday(new Holiday( + 'walpurgisEve', + [], + new DateTime("$this->year-4-30", new DateTimeZone($this->timezone)), + $this->locale, + Holiday::TYPE_OBSERVANCE + )); + } + /** * St. John's Day / Midsummer. * @@ -81,14 +141,24 @@ public function initialize(): void * @throws \Yasumi\Exception\UnknownLocaleException * @throws \Exception */ - private function calculateStJohnsDay(): void + private function calculateStJohnsHolidays(): void { + $date = new DateTime("$this->year-6-20 this saturday", new DateTimeZone($this->timezone)); $this->addHoliday(new Holiday( 'stJohnsDay', [], - new DateTime("$this->year-6-20 this saturday", new DateTimeZone($this->timezone)), + $date, $this->locale )); + + $date->sub(new DateInterval('P1D')); + $this->addHoliday(new Holiday( + 'stJohnsEve', + [], + $date, + $this->locale, + Holiday::TYPE_OBSERVANCE + )); } /** @@ -112,14 +182,24 @@ private function calculateStJohnsDay(): void * @throws \Yasumi\Exception\UnknownLocaleException * @throws \Exception */ - private function calculateAllSaintsDay(): void + private function calculateAllSaintsHolidays(): void { + $date = new DateTime("$this->year-10-31 this saturday", new DateTimeZone($this->timezone)); $this->addHoliday(new Holiday( 'allSaintsDay', [], - new DateTime("$this->year-10-31 this saturday", new DateTimeZone($this->timezone)), + $date, $this->locale )); + + $date->sub(new DateInterval('P1D')); + $this->addHoliday(new Holiday( + 'allSaintsEve', + [], + $date, + $this->locale, + Holiday::TYPE_OBSERVANCE + )); } /** diff --git a/src/Yasumi/data/translations/allSaintsEve.php b/src/Yasumi/data/translations/allSaintsEve.php new file mode 100755 index 000000000..20a902d7b --- /dev/null +++ b/src/Yasumi/data/translations/allSaintsEve.php @@ -0,0 +1,18 @@ + + */ + +// Translations for All Saints' Eve +return [ + 'da_DK' => 'Allehelgensaften', + 'en_US' => 'All Saints\' Eve', + 'sv_SE' => 'alla helgons afton', +]; diff --git a/src/Yasumi/data/translations/epiphanyEve.php b/src/Yasumi/data/translations/epiphanyEve.php new file mode 100644 index 000000000..d2c8ba509 --- /dev/null +++ b/src/Yasumi/data/translations/epiphanyEve.php @@ -0,0 +1,18 @@ + + */ + +// Translations for Epiphany Eve +return [ + 'da_DK' => 'Helligtrekongersaften', + 'en_US' => 'Epiphany Eve', + 'sv_SE' => 'trettondagsafton', +]; diff --git a/src/Yasumi/data/translations/newYearsEve.php b/src/Yasumi/data/translations/newYearsEve.php index 0a6a6133c..56de73ade 100755 --- a/src/Yasumi/data/translations/newYearsEve.php +++ b/src/Yasumi/data/translations/newYearsEve.php @@ -16,4 +16,5 @@ 'en_US' => 'New Year\'s Eve', 'ko_KR' => '신년전야', 'lv_LV' => 'Vecgada vakars', + 'sv_SE' => 'nyårsafton', ]; diff --git a/src/Yasumi/data/translations/stJohnsDay.php b/src/Yasumi/data/translations/stJohnsDay.php index 3e2b272e6..6907dda89 100644 --- a/src/Yasumi/data/translations/stJohnsDay.php +++ b/src/Yasumi/data/translations/stJohnsDay.php @@ -12,6 +12,7 @@ // Translations for St. John's Day return [ + 'da_DK' => 'Sankthansaften', 'el_GR' => 'Σύναξις Προφήτου Προδρόμου και Βαπτιστού Ιωάννου', 'en_US' => 'St. John\'s Day', 'es_ES' => 'Sant Joan', diff --git a/src/Yasumi/data/translations/stJohnsEve.php b/src/Yasumi/data/translations/stJohnsEve.php new file mode 100644 index 000000000..b979daa37 --- /dev/null +++ b/src/Yasumi/data/translations/stJohnsEve.php @@ -0,0 +1,18 @@ + + */ + +// Translations for St. John's Eve +return [ + 'da_DK' => 'Sankthansaften', + 'en_US' => 'St. John\'s Eve', + 'sv_SE' => 'midsommarafton', +]; diff --git a/src/Yasumi/data/translations/walpurgisEve.php b/src/Yasumi/data/translations/walpurgisEve.php new file mode 100755 index 000000000..3570a04a1 --- /dev/null +++ b/src/Yasumi/data/translations/walpurgisEve.php @@ -0,0 +1,17 @@ + + */ + +// Translations for Walpurgis Night +return [ + 'en_US' => 'Walpurgis Night', + 'sv_SE' => 'valborgsmässoafton', +]; diff --git a/tests/Sweden/AllSaintsEveTest.php b/tests/Sweden/AllSaintsEveTest.php new file mode 100644 index 000000000..3897206ba --- /dev/null +++ b/tests/Sweden/AllSaintsEveTest.php @@ -0,0 +1,95 @@ + + */ + +namespace Yasumi\tests\Sweden; + +use DateInterval; +use DateTime; +use DateTimeZone; +use Yasumi\Holiday; +use Yasumi\tests\YasumiTestCaseInterface; + +/** + * Class for testing All Saints' Eve in Sweden. + */ +class AllSaintsEveTest extends SwedenBaseTestCase implements YasumiTestCaseInterface +{ + /** + * The name of the holiday to be tested + */ + public const HOLIDAY = 'allSaintsEve'; + + /** + * Tests the holiday defined in this test. + * + * @dataProvider HolidayDataProvider + * + * @param int $year the year for which the holiday defined in this test needs to be tested + * @param DateTime $expected the expected date + * + * @throws \ReflectionException + */ + public function testHoliday($year, $expected) + { + $this->assertHoliday(self::REGION, self::HOLIDAY, $year, $expected); + } + + /** + * Returns a list of random test dates used for assertion of the holiday defined in this test + * + * @return array list of test dates for the holiday defined in this test + * @throws \Exception + */ + public function HolidayDataProvider(): array + { + $data = []; + + for ($y = 0; $y < 50; $y++) { + $year = $this->generateRandomYear(); + $date = new DateTime("$year-10-30", new DateTimeZone(self::TIMEZONE)); + + // Check between 30 October and 5th of November the day that is a Friday + for ($d = 0; $d <= 7; ++$d) { + if ($date->format('l') === 'Friday') { + $data[] = [$year, $date]; + break; + } + $date->add(new DateInterval('P1D')); + } + } + + return $data; + } + + /** + * Tests the translated name of the holiday defined in this test. + * @throws \ReflectionException + */ + public function testTranslation(): void + { + $this->assertTranslatedHolidayName( + self::REGION, + self::HOLIDAY, + $this->generateRandomYear(), + [self::LOCALE => 'alla helgons afton'] + ); + } + + /** + * Tests type of the holiday defined in this test. + * @throws \ReflectionException + */ + public function testHolidayType(): void + { + $this->assertHolidayType(self::REGION, self::HOLIDAY, $this->generateRandomYear(), Holiday::TYPE_OBSERVANCE); + } +} diff --git a/tests/Sweden/ChristmasEveTest.php b/tests/Sweden/ChristmasEveTest.php index d0c7eb967..2502f163e 100644 --- a/tests/Sweden/ChristmasEveTest.php +++ b/tests/Sweden/ChristmasEveTest.php @@ -72,6 +72,6 @@ public function testTranslation(): void */ public function testHolidayType(): void { - $this->assertHolidayType(self::REGION, self::HOLIDAY, $this->generateRandomYear(), Holiday::TYPE_OFFICIAL); + $this->assertHolidayType(self::REGION, self::HOLIDAY, $this->generateRandomYear(), Holiday::TYPE_OBSERVANCE); } } diff --git a/tests/Sweden/EpiphanyEveTest.php b/tests/Sweden/EpiphanyEveTest.php new file mode 100644 index 000000000..ab72505f2 --- /dev/null +++ b/tests/Sweden/EpiphanyEveTest.php @@ -0,0 +1,77 @@ + + */ + +namespace Yasumi\tests\Sweden; + +use DateTime; +use Yasumi\Holiday; +use Yasumi\tests\YasumiTestCaseInterface; + +/** + * Class containing tests for Epiphany Eve in Sweden. + */ +class EpiphanyEveTest extends SwedenBaseTestCase implements YasumiTestCaseInterface +{ + /** + * The name of the holiday to be tested + */ + public const HOLIDAY = 'epiphanyEve'; + + /** + * Tests the holiday defined in this test. + * + * @dataProvider HolidayDataProvider + * + * @param int $year the year for which the holiday defined in this test needs to be tested + * @param DateTime $expected the expected date + * + * @throws \ReflectionException + */ + public function testHoliday($year, $expected) + { + $this->assertHoliday(self::REGION, self::HOLIDAY, $year, $expected); + } + + /** + * Returns a list of random test dates used for assertion of the holiday defined in this test. + * + * @return array list of test dates for the day of the holiday defined in this test + * @throws \Exception + */ + public function HolidayDataProvider(): array + { + return $this->generateRandomDates(1, 5, self::TIMEZONE); + } + + /** + * Tests the translated name of the holiday defined in this test. + * @throws \ReflectionException + */ + public function testTranslation(): void + { + $this->assertTranslatedHolidayName( + self::REGION, + self::HOLIDAY, + $this->generateRandomYear(), + [self::LOCALE => 'trettondagsafton'] + ); + } + + /** + * Tests type of the holiday defined in this test. + * @throws \ReflectionException + */ + public function testHolidayType(): void + { + $this->assertHolidayType(self::REGION, self::HOLIDAY, $this->generateRandomYear(), Holiday::TYPE_OBSERVANCE); + } +} diff --git a/tests/Sweden/NewYearsEveTest.php b/tests/Sweden/NewYearsEveTest.php new file mode 100644 index 000000000..33508ffbd --- /dev/null +++ b/tests/Sweden/NewYearsEveTest.php @@ -0,0 +1,77 @@ + + */ + +namespace Yasumi\tests\Sweden; + +use DateTime; +use Yasumi\Holiday; +use Yasumi\tests\YasumiTestCaseInterface; + +/** + * Class for testing New Year's Eve in Sweden. + */ +class NewYearsEveTest extends SwedenBaseTestCase implements YasumiTestCaseInterface +{ + /** + * The name of the holiday to be tested + */ + public const HOLIDAY = 'newYearsEve'; + + /** + * Tests the holiday defined in this test. + * + * @dataProvider HolidayDataProvider + * + * @param int $year the year for which the holiday defined in this test needs to be tested + * @param DateTime $expected the expected date + * + * @throws \ReflectionException + */ + public function testHoliday($year, $expected) + { + $this->assertHoliday(self::REGION, self::HOLIDAY, $year, $expected); + } + + /** + * Returns a list of random test dates used for assertion of the holiday defined in this test + * + * @return array list of test dates for the holiday defined in this test + * @throws \Exception + */ + public function HolidayDataProvider(): array + { + return $this->generateRandomDates(12, 31, self::TIMEZONE); + } + + /** + * Tests the translated name of the holiday defined in this test. + * @throws \ReflectionException + */ + public function testTranslation(): void + { + $this->assertTranslatedHolidayName( + self::REGION, + self::HOLIDAY, + $this->generateRandomYear(), + [self::LOCALE => 'nyårsafton'] + ); + } + + /** + * Tests type of the holiday defined in this test. + * @throws \ReflectionException + */ + public function testHolidayType(): void + { + $this->assertHolidayType(self::REGION, self::HOLIDAY, $this->generateRandomYear(), Holiday::TYPE_OBSERVANCE); + } +} diff --git a/tests/Sweden/stJohnsDayTest.php b/tests/Sweden/StJohnsDayTest.php similarity index 97% rename from tests/Sweden/stJohnsDayTest.php rename to tests/Sweden/StJohnsDayTest.php index b70c108c5..a3039c38d 100644 --- a/tests/Sweden/stJohnsDayTest.php +++ b/tests/Sweden/StJohnsDayTest.php @@ -19,7 +19,7 @@ /** * Class for testing St. John's Day / Midsummer's Day in Sweden. */ -class stJohnsDayTest extends SwedenBaseTestCase implements YasumiTestCaseInterface +class StJohnsDayTest extends SwedenBaseTestCase implements YasumiTestCaseInterface { /** * The name of the holiday to be tested diff --git a/tests/Sweden/StJohnsEveTest.php b/tests/Sweden/StJohnsEveTest.php new file mode 100644 index 000000000..6f030e8d9 --- /dev/null +++ b/tests/Sweden/StJohnsEveTest.php @@ -0,0 +1,75 @@ + + */ + +namespace Yasumi\tests\Sweden; + +use Yasumi\Holiday; +use Yasumi\tests\YasumiTestCaseInterface; +use Yasumi\Yasumi; + +/** + * Class for testing St. John's Eve / Midsummer's Eve in Sweden. + */ +class StJohnsEveTest extends SwedenBaseTestCase implements YasumiTestCaseInterface +{ + /** + * The name of the holiday to be tested + */ + public const HOLIDAY = 'stJohnsEve'; + + /** + * Tests the holiday defined in this test. + * @throws \ReflectionException + */ + public function testHoliday() + { + $year = $this->generateRandomYear(); + + $holidays = Yasumi::create(self::REGION, $year); + $holiday = $holidays->getHoliday(self::HOLIDAY); + + // Some basic assertions + $this->assertInstanceOf('Yasumi\Provider\\' . \str_replace('/', '\\', self::REGION), $holidays); + $this->assertInstanceOf(Holiday::class, $holiday); + $this->assertNotNull($holiday); + + // Holiday specific assertions + $this->assertEquals('Friday', $holiday->format('l')); + $this->assertGreaterThanOrEqual(19, $holiday->format('j')); + $this->assertLessThanOrEqual(25, $holiday->format('j')); + + unset($holiday, $holidays); + } + + /** + * Tests the translated name of the holiday defined in this test. + * @throws \ReflectionException + */ + public function testTranslation(): void + { + $this->assertTranslatedHolidayName( + self::REGION, + self::HOLIDAY, + $this->generateRandomYear(), + [self::LOCALE => 'midsommarafton'] + ); + } + + /** + * Tests type of the holiday defined in this test. + * @throws \ReflectionException + */ + public function testHolidayType(): void + { + $this->assertHolidayType(self::REGION, self::HOLIDAY, $this->generateRandomYear(), Holiday::TYPE_OBSERVANCE); + } +} diff --git a/tests/Sweden/SwedenTest.php b/tests/Sweden/SwedenTest.php index a9b56c57b..f58706af6 100644 --- a/tests/Sweden/SwedenTest.php +++ b/tests/Sweden/SwedenTest.php @@ -42,7 +42,6 @@ public function testOfficialHolidays(): void 'nationalDay', 'stJohnsDay', // Midsummer's Day 'allSaintsDay', - 'christmasEve', 'christmasDay', 'secondChristmasDay' ], self::REGION, $this->year, Holiday::TYPE_OFFICIAL); @@ -54,7 +53,14 @@ public function testOfficialHolidays(): void */ public function testObservedHolidays(): void { - $this->assertDefinedHolidays([], self::REGION, $this->year, Holiday::TYPE_OBSERVANCE); + $this->assertDefinedHolidays([ + 'epiphanyEve', + 'walpurgisEve', + 'stJohnsEve', + 'allSaintsEve', + 'christmasEve', + 'newYearsEve', + ], self::REGION, $this->year, Holiday::TYPE_OBSERVANCE); } /** diff --git a/tests/Sweden/WalpurgisEveTest.php b/tests/Sweden/WalpurgisEveTest.php new file mode 100644 index 000000000..86916f8b6 --- /dev/null +++ b/tests/Sweden/WalpurgisEveTest.php @@ -0,0 +1,77 @@ + + */ + +namespace Yasumi\tests\Sweden; + +use DateTime; +use Yasumi\Holiday; +use Yasumi\tests\YasumiTestCaseInterface; + +/** + * Class containing tests for Walpurgis Night in Sweden. + */ +class WalpurgisEveTest extends SwedenBaseTestCase implements YasumiTestCaseInterface +{ + /** + * The name of the holiday to be tested + */ + public const HOLIDAY = 'walpurgisEve'; + + /** + * Tests the holiday defined in this test. + * + * @dataProvider HolidayDataProvider + * + * @param int $year the year for which the holiday defined in this test needs to be tested + * @param DateTime $expected the expected date + * + * @throws \ReflectionException + */ + public function testHoliday($year, $expected) + { + $this->assertHoliday(self::REGION, self::HOLIDAY, $year, $expected); + } + + /** + * Returns a list of random test dates used for assertion of the holiday defined in this test. + * + * @return array list of test dates for the day of the holiday defined in this test + * @throws \Exception + */ + public function HolidayDataProvider(): array + { + return $this->generateRandomDates(4, 30, self::TIMEZONE); + } + + /** + * Tests the translated name of the holiday defined in this test. + * @throws \ReflectionException + */ + public function testTranslation(): void + { + $this->assertTranslatedHolidayName( + self::REGION, + self::HOLIDAY, + $this->generateRandomYear(), + [self::LOCALE => 'valborgsmässoafton'] + ); + } + + /** + * Tests type of the holiday defined in this test. + * @throws \ReflectionException + */ + public function testHolidayType(): void + { + $this->assertHolidayType(self::REGION, self::HOLIDAY, $this->generateRandomYear(), Holiday::TYPE_OBSERVANCE); + } +}