diff --git a/src/Yasumi/Provider/CommonHolidays.php b/src/Yasumi/Provider/CommonHolidays.php index 75bcebaf2..005191665 100644 --- a/src/Yasumi/Provider/CommonHolidays.php +++ b/src/Yasumi/Provider/CommonHolidays.php @@ -23,6 +23,37 @@ */ trait CommonHolidays { + /** + * New Year's Eve. + * + * New Year's Eve is observed on December 31, the last day of the year on the modern Gregorian calendar as well as + * the Julian calendar. In present day, with most countries now using the Gregorian calendar as their de facto calendar, + * New Year's Eve is probably the most celebrated holiday, often observed with fireworks at the stroke of midnight as + * the new year starts in each time zone. + * + * @link http://en.wikipedia.org/wiki/New_Year%27s_Eve + * + * @param int $year the year for which New Year's Eve need to be created + * @param string $timezone the timezone in which New Year's Eve is celebrated + * @param string $locale the locale for which New Year's Eve need to be displayed in. + * @param string $type The type of holiday. Use the following constants: TYPE_OFFICIAL, TYPE_OBSERVANCE, + * TYPE_SEASON, TYPE_BANK or TYPE_OTHER. By default an official holiday is considered. + * + * @return \Yasumi\Holiday + * + * @throws \Yasumi\Exception\InvalidDateException + * @throws \Yasumi\Exception\UnknownLocaleException + * @throws \InvalidArgumentException + */ + public function newYearsEve( + int $year, + string $timezone, + string $locale, + string $type = Holiday::TYPE_OFFICIAL + ): Holiday { + return new Holiday('newYearsEve', [], new DateTime("$year-12-31", new DateTimeZone($timezone)), $locale, $type); + } + /** * New Year's Day. * diff --git a/src/Yasumi/Provider/Denmark.php b/src/Yasumi/Provider/Denmark.php index 84b1f7292..f84c14571 100644 --- a/src/Yasumi/Provider/Denmark.php +++ b/src/Yasumi/Provider/Denmark.php @@ -55,9 +55,21 @@ public function initialize() $this->addHoliday($this->pentecostMonday($this->year, $this->timezone, $this->locale)); $this->addHoliday($this->christmasDay($this->year, $this->timezone, $this->locale)); $this->addHoliday($this->secondChristmasDay($this->year, $this->timezone, $this->locale)); - - // Calculate other holidays $this->calculateGreatPrayerDay(); + + $this->addHoliday($this->internationalWorkersDay($this->year, $this->timezone, $this->locale, Holiday::TYPE_OBSERVANCE)); + $this->addHoliday($this->christmasEve($this->year, $this->timezone, $this->locale, Holiday::TYPE_OBSERVANCE)); + $this->addHoliday($this->newYearsEve($this->year, $this->timezone, $this->locale, Holiday::TYPE_OBSERVANCE)); + $this->calculateConstitutionDay(); + + $summerTime = $this->summerTime($this->year, $this->timezone, $this->locale); + if ($summerTime) { + $this->addHoliday($summerTime); + } + $winterTime = $this->winterTime($this->year, $this->timezone, $this->locale); + if ($winterTime) { + $this->addHoliday($winterTime); + } } /** @@ -89,4 +101,32 @@ public function calculateGreatPrayerDay() )); } } + + /** + * Constitution Day + * + * Denmark’s Constitution Day is June 5 and commemorates the signing of Denmark's constitution + * on June 5 1849, when Denmark peacefully became as a constitutional monarchy. + * + * While not a public holiday, some companies and public offices are closed. Traditionally, + * members of parliament gives political speeches around the country. + * + * @link https://en.wikipedia.org/wiki/Constitution_Day_(Denmark) + * + * @throws \Yasumi\Exception\InvalidDateException + * @throws \InvalidArgumentException + * @throws \Yasumi\Exception\UnknownLocaleException + */ + public function calculateConstitutionDay() + { + if ($this->year >= 1849) { + $this->addHoliday(new Holiday( + 'constitutionDay', + ['da_DK' => 'Grundlovsdag'], + new DateTime("$this->year-6-5", new DateTimeZone($this->timezone)), + $this->locale, + Holiday::TYPE_OBSERVANCE + )); + } + } } diff --git a/src/Yasumi/Provider/Latvia.php b/src/Yasumi/Provider/Latvia.php index bcbac40a4..5662cdf19 100644 --- a/src/Yasumi/Provider/Latvia.php +++ b/src/Yasumi/Provider/Latvia.php @@ -57,7 +57,7 @@ public function initialize() $this->addHoliday($this->christmasEve($this->year, $this->timezone, $this->locale, Holiday::TYPE_OFFICIAL)); $this->addHoliday($this->christmasDay($this->year, $this->timezone, $this->locale)); $this->addHoliday($this->secondChristmasDay($this->year, $this->timezone, $this->locale)); - $this->addNewYearsEve(); + $this->addHoliday($this->newYearsEve($this->year, $this->timezone, $this->locale)); } /** @@ -116,15 +116,4 @@ private function addProclamationDay() ], $date)); } } - - /** - * @throws \InvalidArgumentException - */ - private function addNewYearsEve() - { - $this->addHoliday(new Holiday('newYearsEve', [ - 'en_US' => 'New Year\'s Eve', - 'lv_LV' => 'Vecgada vakars' - ], new \DateTime("{$this->year}-12-31", new \DateTimeZone($this->timezone)))); - } } diff --git a/src/Yasumi/Provider/Norway.php b/src/Yasumi/Provider/Norway.php index 5efa7c115..072d057e6 100644 --- a/src/Yasumi/Provider/Norway.php +++ b/src/Yasumi/Provider/Norway.php @@ -70,7 +70,7 @@ public function initialize() * coalition with Sweden, proceeded by nearly 400 years of Danish rule. The Norwegian Parliament, known as * Stortinget, held the first May 17 celebrations in 1836, and since it has been regarded as Norway’s National Day. * - * @link https://en.wikipedia.org/wiki/Store_Bededag + * @link https://en.wikipedia.org/wiki/Norwegian_Constitution_Day * * @throws \Yasumi\Exception\InvalidDateException * @throws \InvalidArgumentException diff --git a/src/Yasumi/data/translations/christmasEve.php b/src/Yasumi/data/translations/christmasEve.php index 697598908..884820b48 100755 --- a/src/Yasumi/data/translations/christmasEve.php +++ b/src/Yasumi/data/translations/christmasEve.php @@ -14,6 +14,7 @@ return [ 'cs_CZ' => 'Štědrý den', 'cy_GB' => 'Noswyl Nadolig', + 'da_DK' => 'Juleaften', 'de_CH' => 'Heiliger Abend', 'en_US' => 'Christmas Eve', 'et_EE' => 'Jõululaupäev', diff --git a/src/Yasumi/data/translations/internationalWorkersDay.php b/src/Yasumi/data/translations/internationalWorkersDay.php index 584845034..c27ca11ec 100755 --- a/src/Yasumi/data/translations/internationalWorkersDay.php +++ b/src/Yasumi/data/translations/internationalWorkersDay.php @@ -14,6 +14,7 @@ return [ 'bs_Latn_BA' => 'Praznik rada', 'cs_CZ' => 'Svátek práce', + 'da_DK' => 'Første maj', 'de_AT' => 'Staatsfeiertag', 'de_CH' => 'Tag der Arbeit', 'de_DE' => 'Tag der Arbeit', diff --git a/src/Yasumi/data/translations/newYearsEve.php b/src/Yasumi/data/translations/newYearsEve.php new file mode 100755 index 000000000..5d1154da0 --- /dev/null +++ b/src/Yasumi/data/translations/newYearsEve.php @@ -0,0 +1,18 @@ + + */ + +// Translations for New Year's Eve +return [ + 'en_US' => 'New Year\'s Eve', + 'da_DK' => 'Nytårsaften', + 'lv_LV' => 'Vecgada vakars' +]; diff --git a/src/Yasumi/data/translations/summerTime.php b/src/Yasumi/data/translations/summerTime.php index a7d935300..89bfc2efb 100644 --- a/src/Yasumi/data/translations/summerTime.php +++ b/src/Yasumi/data/translations/summerTime.php @@ -12,6 +12,7 @@ // Translations for daylight saving time start. return [ + 'da_DK' => 'Sommertid starter', 'en_US' => 'Summertime', 'nl_NL' => 'Zomertijd', ]; diff --git a/src/Yasumi/data/translations/winterTime.php b/src/Yasumi/data/translations/winterTime.php index 656da9297..b86595bdc 100644 --- a/src/Yasumi/data/translations/winterTime.php +++ b/src/Yasumi/data/translations/winterTime.php @@ -12,6 +12,7 @@ // Translations for daylight saving time end. return [ + 'da_DK' => 'Sommertid slutter', 'en_US' => 'Wintertime', 'nl_NL' => 'Wintertijd', ]; diff --git a/tests/Denmark/ChristmasEveTest.php b/tests/Denmark/ChristmasEveTest.php new file mode 100644 index 000000000..a59610157 --- /dev/null +++ b/tests/Denmark/ChristmasEveTest.php @@ -0,0 +1,72 @@ + + */ + +namespace Yasumi\tests\Denmark; + +use DateTime; +use Yasumi\Holiday; +use Yasumi\tests\YasumiTestCaseInterface; + +/** + * Class for testing Christmas Eve in Denmark. + */ +class ChristmasEveTest extends DenmarkBaseTestCase implements YasumiTestCaseInterface +{ + /** + * The name of the holiday to be tested + */ + const HOLIDAY = 'christmasEve'; + + /** + * 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 + */ + 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 + */ + public function HolidayDataProvider(): array + { + return $this->generateRandomDates(12, 24, self::TIMEZONE); + } + + /** + * Tests the translated name of the holiday defined in this test. + */ + public function testTranslation() + { + $this->assertTranslatedHolidayName( + self::REGION, + self::HOLIDAY, + $this->generateRandomYear(), + [self::LOCALE => 'Juleaften'] + ); + } + + /** + * Tests type of the holiday defined in this test. + */ + public function testHolidayType() + { + $this->assertHolidayType(self::REGION, self::HOLIDAY, $this->generateRandomYear(), Holiday::TYPE_OBSERVANCE); + } +} diff --git a/tests/Denmark/ConstitutionDayTest.php b/tests/Denmark/ConstitutionDayTest.php new file mode 100644 index 000000000..8fd254038 --- /dev/null +++ b/tests/Denmark/ConstitutionDayTest.php @@ -0,0 +1,86 @@ + + */ + +namespace Yasumi\tests\Denmark; + +use DateTime; +use DateTimeZone; +use Yasumi\Holiday; +use Yasumi\tests\YasumiTestCaseInterface; + +/** + * Class for testing the Constitution Day of Denmark. + */ +class ConstitutionDayTest extends DenmarkBaseTestCase implements YasumiTestCaseInterface +{ + /** + * The name of the holiday to be tested + */ + const HOLIDAY = 'constitutionDay'; + + /** + * The year in which the holiday was first established + */ + const ESTABLISHMENT_YEAR = 1849; + + /** + * Tests the holiday defined in this test on or after establishment. + */ + public function testHolidayOnAfterEstablishment() + { + $year = 2077; + $this->assertHoliday( + self::REGION, + self::HOLIDAY, + $year, + new DateTime("$year-6-5", new DateTimeZone(self::TIMEZONE)) + ); + } + + /** + * Tests the holiday defined in this test before establishment. + */ + public function testHolidayBeforeEstablishment() + { + $this->assertNotHoliday( + self::REGION, + self::HOLIDAY, + $this->generateRandomYear(1000, self::ESTABLISHMENT_YEAR - 1) + ); + } + + /** + * Tests the translated name of the holiday defined in this test. + */ + public function testTranslation() + { + $this->assertTranslatedHolidayName( + self::REGION, + self::HOLIDAY, + $this->generateRandomYear(self::ESTABLISHMENT_YEAR), + [self::LOCALE => 'Grundlovsdag'] + ); + } + + /** + * Tests type of the holiday defined in this test. + */ + public function testHolidayType() + { + $this->assertHolidayType( + self::REGION, + self::HOLIDAY, + $this->generateRandomYear(self::ESTABLISHMENT_YEAR), + Holiday::TYPE_OBSERVANCE + ); + } +} diff --git a/tests/Denmark/DenmarkTest.php b/tests/Denmark/DenmarkTest.php index ce0f08c50..d8c0b242d 100644 --- a/tests/Denmark/DenmarkTest.php +++ b/tests/Denmark/DenmarkTest.php @@ -49,7 +49,12 @@ public function testOfficialHolidays() */ public function testObservedHolidays() { - $this->assertDefinedHolidays([], self::REGION, $this->year, Holiday::TYPE_OBSERVANCE); + $this->assertDefinedHolidays([ + 'internationalWorkersDay', + 'constitutionDay', + 'christmasEve', + 'newYearsEve', + ], self::REGION, $this->year, Holiday::TYPE_OBSERVANCE); } /** @@ -57,7 +62,8 @@ public function testObservedHolidays() */ public function testSeasonalHolidays() { - $this->assertDefinedHolidays([], self::REGION, $this->year, Holiday::TYPE_SEASON); + $year = $this->generateRandomYear(1980, 2037); + $this->assertDefinedHolidays(['summerTime', 'winterTime'], self::REGION, $year, Holiday::TYPE_SEASON); } /** @@ -81,6 +87,6 @@ public function testOtherHolidays() */ protected function setUp() { - $this->year = $this->generateRandomYear(1686); + $this->year = $this->generateRandomYear(1849); } } diff --git a/tests/Denmark/InternationalWorkersDayTest.php b/tests/Denmark/InternationalWorkersDayTest.php new file mode 100644 index 000000000..63c289b99 --- /dev/null +++ b/tests/Denmark/InternationalWorkersDayTest.php @@ -0,0 +1,72 @@ + + */ + +namespace Yasumi\tests\Denmark; + +use DateTime; +use Yasumi\Holiday; +use Yasumi\tests\YasumiTestCaseInterface; + +/** + * Class containing tests for International Workers' Day (i.e. Labour Day) in Denmark. + */ +class InternationalWorkersDayTest extends DenmarkBaseTestCase implements YasumiTestCaseInterface +{ + /** + * The name of the holiday + */ + const HOLIDAY = 'internationalWorkersDay'; + + /** + * Tests International Workers' Day. + * + * @dataProvider InternationalWorkersDayDataProvider + * + * @param int $year the year for which International Workers' Day needs to be tested + * @param DateTime $expected the expected date + */ + public function testInternationalWorkersDay($year, $expected) + { + $this->assertHoliday(self::REGION, self::HOLIDAY, $year, $expected); + } + + /** + * Returns a list of random test dates used for assertion of International Workers' Day. + * + * @return array list of test dates for International Workers' Day + */ + public function InternationalWorkersDayDataProvider(): array + { + return $this->generateRandomDates(5, 1, self::TIMEZONE); + } + + /** + * Tests the translated name of the holiday defined in this test. + */ + public function testTranslation() + { + $this->assertTranslatedHolidayName( + self::REGION, + self::HOLIDAY, + $this->generateRandomYear(), + [self::LOCALE => 'Første maj'] + ); + } + + /** + * Tests type of the holiday defined in this test. + */ + public function testHolidayType() + { + $this->assertHolidayType(self::REGION, self::HOLIDAY, $this->generateRandomYear(), Holiday::TYPE_OBSERVANCE); + } +} diff --git a/tests/Denmark/NewYearsEveTest.php b/tests/Denmark/NewYearsEveTest.php new file mode 100644 index 000000000..4bda6d650 --- /dev/null +++ b/tests/Denmark/NewYearsEveTest.php @@ -0,0 +1,72 @@ + + */ + +namespace Yasumi\tests\Denmark; + +use DateTime; +use Yasumi\Holiday; +use Yasumi\tests\YasumiTestCaseInterface; + +/** + * Class for testing New Years Eve in Denmark. + */ +class NewYearsEveTest extends DenmarkBaseTestCase implements YasumiTestCaseInterface +{ + /** + * The name of the holiday to be tested + */ + 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 + */ + 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 + */ + public function HolidayDataProvider(): array + { + return $this->generateRandomDates(12, 31, self::TIMEZONE); + } + + /** + * Tests the translated name of the holiday defined in this test. + */ + public function testTranslation() + { + $this->assertTranslatedHolidayName( + self::REGION, + self::HOLIDAY, + $this->generateRandomYear(), + [self::LOCALE => 'Nytårsaften'] + ); + } + + /** + * Tests type of the holiday defined in this test. + */ + public function testHolidayType() + { + $this->assertHolidayType(self::REGION, self::HOLIDAY, $this->generateRandomYear(), Holiday::TYPE_OBSERVANCE); + } +} diff --git a/tests/Denmark/SummerTimeTest.php b/tests/Denmark/SummerTimeTest.php new file mode 100644 index 000000000..297d7ea29 --- /dev/null +++ b/tests/Denmark/SummerTimeTest.php @@ -0,0 +1,66 @@ + + */ + +namespace Yasumi\tests\Denmark; + +use DateTime; +use DateTimeZone; +use Yasumi\Holiday; +use Yasumi\tests\YasumiTestCaseInterface; + +/** + * Class for testing summer time in Denmark. + */ +class SummerTimeTest extends DenmarkBaseTestCase implements YasumiTestCaseInterface +{ + /** + * The name of the holiday + */ + const HOLIDAY = 'summerTime'; + + /** + * Tests the holiday defined in this test. + */ + public function testSummerTime() + { + $this->assertNotHoliday(self::REGION, self::HOLIDAY, $this->generateRandomYear(1949, 1979)); + + $year = $this->generateRandomYear(1980, 2036); + $this->assertHoliday( + self::REGION, + self::HOLIDAY, + $year, + new DateTime("last sunday of march $year", new DateTimeZone(self::TIMEZONE)) + ); + } + + /** + * Tests the translated name of the holiday defined in this test. + */ + public function testTranslation() + { + $this->assertTranslatedHolidayName( + self::REGION, + self::HOLIDAY, + $this->generateRandomYear(1980, 2037), + [self::LOCALE => 'Sommertid starter'] + ); + } + + /** + * Tests type of the holiday defined in this test. + */ + public function testHolidayType() + { + $this->assertHolidayType(self::REGION, self::HOLIDAY, $this->generateRandomYear(1980, 2037), Holiday::TYPE_SEASON); + } +} diff --git a/tests/Denmark/WinterTimeTest.php b/tests/Denmark/WinterTimeTest.php new file mode 100644 index 000000000..f68558c53 --- /dev/null +++ b/tests/Denmark/WinterTimeTest.php @@ -0,0 +1,74 @@ + + */ + +namespace Yasumi\tests\Denmark; + +use DateTime; +use DateTimeZone; +use Yasumi\Holiday; +use Yasumi\tests\YasumiTestCaseInterface; + +/** + * Class for testing winter time in Denmark. + */ +class WinterTimeTest extends DenmarkBaseTestCase implements YasumiTestCaseInterface +{ + /** + * The name of the holiday + */ + const HOLIDAY = 'winterTime'; + + /** + * Tests the holiday defined in this test. + */ + public function testWinterTime() + { + $this->assertNotHoliday(self::REGION, self::HOLIDAY, $this->generateRandomYear(1949, 1979)); + + $year = $this->generateRandomYear(1980, 1995); + $this->assertHoliday( + self::REGION, + self::HOLIDAY, + $year, + new DateTime("last sunday of september $year", new DateTimeZone(self::TIMEZONE)) + ); + + $year = $this->generateRandomYear(1996, 2036); + $this->assertHoliday( + self::REGION, + self::HOLIDAY, + $year, + new DateTime("last sunday of october $year", new DateTimeZone(self::TIMEZONE)) + ); + } + + /** + * Tests the translated name of the holiday defined in this test. + */ + public function testTranslation() + { + $this->assertTranslatedHolidayName( + self::REGION, + self::HOLIDAY, + $this->generateRandomYear(1980, 2037), + [self::LOCALE => 'Sommertid slutter'] + ); + } + + /** + * Tests type of the holiday defined in this test. + */ + public function testHolidayType() + { + $this->assertHolidayType(self::REGION, self::HOLIDAY, $this->generateRandomYear(1980, 2037), Holiday::TYPE_SEASON); + } +}