Skip to content

Commit

Permalink
Merge pull request #23 from azuyalabs/uk-provider
Browse files Browse the repository at this point in the history
Added United Kingdom Holiday Provider
  • Loading branch information
stelgenhof committed May 2, 2016
2 parents a48a12a + 20053ed commit c33dcc1
Show file tree
Hide file tree
Showing 16 changed files with 859 additions and 0 deletions.
5 changes: 5 additions & 0 deletions phpunit.xml
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,11 @@
<directory suffix="Test.php">./tests/Poland</directory>
</testsuite>

<!-- Test Suite for holidays in United Kingdom -->
<testsuite name="UnitedKingdom">
<directory suffix="Test.php">./tests/UnitedKingdom</directory>
</testsuite>

</testsuites>
<filter>
<whitelist processUncoveredFilesFromWhitelist="true">
Expand Down
167 changes: 167 additions & 0 deletions src/Yasumi/Provider/UnitedKingdom.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
<?php
/**
* This file is part of the Yasumi package.
*
* Copyright (c) 2015 - 2016 AzuyaLabs
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @author Sacha Telgenhof <stelgenhof@gmail.com>
*/

namespace Yasumi\Provider;

use DateInterval;
use DateTime;
use DateTimeZone;
use Yasumi\Holiday;

/**
* Provider for all holidays in the United Kingdom. Local holidays/observances (e.g. Wales, England, Guernsey, etc.)
* are not part of this provider.
*/
class UnitedKingdom extends AbstractProvider
{
use CommonHolidays, ChristianHolidays;

/**
* Initialize holidays for the United Kingdom.
*/
public function initialize()
{
$this->timezone = 'Europe/London';

// Add common holidays
$this->calculateNewYearsDay();
$this->calculateMayDayBankHoliday();
$this->calculateSpringBankHoliday();

// Add common Christian holidays (common in the United Kingdom)
$this->addHoliday($this->goodFriday($this->year, $this->timezone, $this->locale));
$this->addHoliday($this->easterMonday($this->year, $this->timezone, $this->locale, Holiday::TYPE_BANK));
$this->calculateChristmasHolidays();
}

/**
* New Year's Day is a public holiday in the United Kingdom on January 1 each year. It marks
* the start of the New Year in the Gregorian calendar. For many people have a quiet day on
* January 1, which marks the end of the Christmas break before they return to work.
*
* If New Years Day falls on a Saturday or Sunday, it is observed the next Monday (January 2nd or 3rd)
* Before 1871 it was not an observed or statutory holiday, after 1871 only an observed holiday.
* Since 1974 (by Royal Proclamation) it was established as a bank holiday.
*
* @link https://en.wikipedia.org/wiki/Public_holidays_in_the_United_Kingdom
* @link http://www.timeanddate.com/holidays/uk/new-year-day
*/
public function calculateNewYearsDay()
{
// Before 1871 it was not an observed or statutory holiday
if ($this->year < 1871) {
return;
}

$type = Holiday::TYPE_BANK;
if ($this->year <= 1974) {
$type = Holiday::TYPE_OBSERVANCE;
}

$newYearsDay = new DateTime("$this->year-01-01", new DateTimeZone($this->timezone));

// If New Years Day falls on a Saturday or Sunday, it is observed the next Monday (January 2nd or 3rd)
if (in_array($newYearsDay->format('w'), [0, 6])) {
$newYearsDay->modify('next monday');
}

$this->addHoliday(new Holiday('newYearsDay', [], $newYearsDay, $this->locale, $type));
}

/**
* The first Monday of May is a bank holiday in the United Kingdom. It is called May Day in England, Wales and Northern Ireland.
* It is known as the Early May Bank Holiday in Scotland. It probably originated as a Roman festival honoring the beginning of
* the summer season (in the northern hemisphere). In more recent times, it has been as a day to campaign for and celebrate
* workers' rights.
*
* The first Monday in May is a bank holiday and many people have a day off work. Many organizations, businesses and schools are
* closed, while stores may be open or closed, according to local custom. Public transport systems often run to a holiday timetable.
*
* @link http://www.timeanddate.com/holidays/uk/early-may-bank-holiday
*/
private function calculateMayDayBankHoliday()
{
// From 1978, by Royal Proclamation annually
if ($this->year < 1978) {
return;
}

$this->addHoliday(new Holiday(
'mayDayBankHoliday',
['en_GB' => 'May Day Bank Holiday'],
new DateTime("first monday of may $this->year", new DateTimeZone($this->timezone)),
$this->locale, Holiday::TYPE_BANK
));
}

/**
* The spring bank holiday, also known as the late May bank holiday, is a time for people in the United Kingdom to have a
* day off work or school. It falls on the last Monday of May but it used to be on the Monday after Pentecost.
*
* The last Monday in May is a bank holiday. Many organizations, businesses and schools are closed. Stores may be open
* or closed, according to local custom. Public transport systems often run to a holiday timetable.
*
* @link http://www.timeanddate.com/holidays/uk/spring-bank-holiday
*/
private function calculateSpringBankHoliday()
{
// Statutory bank holiday from 1971, following a trial period from 1965 to 1970.
if ($this->year < 1965) {
return;
}

$this->addHoliday(new Holiday(
'springBankHoliday',
['en_GB' => 'Spring Bank Holiday'],
new DateTime("last monday of may $this->year", new DateTimeZone($this->timezone)),
$this->locale, Holiday::TYPE_BANK
));
}

/**
* Christmas Day is celebrated in the United Kingdom on December 25. It traditionally celebrates Jesus Christ's birth
* but many aspects of this holiday have pagan origins. Christmas is a time for many people to give and receive gifts
* and prepare special festive meals.
*
* Boxing Day in the United Kingdom is the day after Christmas Day and falls on December 26. Traditionally, it was a
* day when employers distributed money, food, cloth (material) or other valuable goods to their employees.
* In modern times, it is an important day for sporting events and the start of the post-Christmas sales.
*
* Boxing Day is a bank holiday. If Boxing Day falls on a Saturday, the following Monday is a bank holiday.
* If Christmas Day falls on a Saturday, the following Monday and Tuesday are bank holidays. All schools and many
* organizations are closed in this period. Some may close for the whole week between Christmas and New Year.
*
* @link http://www.timeanddate.com/holidays/uk/christmas-day
* @link http://www.timeanddate.com/holidays/uk/boxing-day
*/
public function calculateChristmasHolidays()
{
$christmasDay = new DateTime("$this->year-12-25", new DateTimeZone($this->timezone));
$boxingDay = new DateTime("$this->year-12-26", new DateTimeZone($this->timezone));

switch ($christmasDay->format('w')) {
case 0:
$christmasDay->add(new DateInterval('P2D'));
break;
case 5:
$boxingDay->add(new DateInterval('P2D'));
break;
case 6:
$christmasDay->add(new DateInterval('P2D'));
$boxingDay->add(new DateInterval('P2D'));
break;
}

$this->addHoliday(new Holiday('christmasDay', [], $christmasDay, $this->locale));
$this->addHoliday(new Holiday('secondChristmasDay', [], $boxingDay, $this->locale, Holiday::TYPE_BANK));
}
}
1 change: 1 addition & 0 deletions src/Yasumi/data/translations/christmasDay.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
'da_DK' => '1. Juledag',
'de_DE' => '1. Weihnachtsfeiertag',
'el_GR' => 'Χριστούγεννα',
'en_GB' => 'Christmas Day',
'en_NZ' => 'Christmas Day',
'en_US' => 'Christmas',
'es_ES' => 'Navidad',
Expand Down
1 change: 1 addition & 0 deletions src/Yasumi/data/translations/easterMonday.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
'da_DK' => '2. Påskedag',
'de_DE' => 'Ostermontag',
'el_GR' => 'Δευτέρα του Πάσχα',
'en_GB' => 'Easter Monday',
'en_NZ' => 'Easter Monday',
'en_US' => 'Easter Monday',
'es_ES' => 'Lunes de Pascua',
Expand Down
1 change: 1 addition & 0 deletions src/Yasumi/data/translations/goodFriday.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
'da_DK' => 'Langfredag',
'de_DE' => 'Karfreitag',
'el_GR' => 'Μεγάλη Παρασκευή',
'en_GB' => 'Good Friday',
'en_NZ' => 'Good Friday',
'en_US' => 'Good Friday',
'es_ES' => 'Viernes Santo',
Expand Down
1 change: 1 addition & 0 deletions src/Yasumi/data/translations/newYearsDay.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
'da_DK' => 'Nytårsdag',
'de_DE' => 'Neujahr',
'el_GR' => 'Πρωτοχρονιά',
'en_GB' => 'New Year\'s Day',
'en_NZ' => 'New Year\'s Day',
'en_US' => 'New Year\'s Day',
'es_ES' => 'Año Nuevo',
Expand Down
1 change: 1 addition & 0 deletions src/Yasumi/data/translations/secondChristmasDay.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
'da_DK' => '2. Juledag',
'de_DE' => '2. Weihnachtsfeiertag',
'el_GR' => 'Σύναξις Υπεραγίας Θεοτόκου Μαρίας',
'en_GB' => 'Boxing Day',
'en_NZ' => 'Boxing Day',
'en_US' => 'Boxing Day',
'fi_FI' => '2. joulupäivä',
Expand Down
84 changes: 84 additions & 0 deletions tests/UnitedKingdom/BoxingDayTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<?php
/**
* This file is part of the Yasumi package.
*
* Copyright (c) 2015 - 2016 AzuyaLabs
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @author Sacha Telgenhof <stelgenhof@gmail.com>
*/

namespace Yasumi\tests\UnitedKingdom;

use DateInterval;
use DateTime;
use DateTimeZone;
use Yasumi\Holiday;
use Yasumi\tests\YasumiTestCaseInterface;

/**
* Class for testing Boxing Day in the United Kingdom.
*/
class BoxingDayTest extends UnitedKingdomBaseTestCase implements YasumiTestCaseInterface
{
/**
* The name of the holiday
*/
const HOLIDAY = 'secondChristmasDay';

/**
* 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 string $expected the expected date
*/
public function testHoliday($year, $expected)
{
$this->assertHoliday(self::REGION, self::HOLIDAY, $year,
new DateTime($expected, new DateTimeZone(self::TIMEZONE)));
}

/**
* Returns a list of test dates
*
* @return array list of test dates for the holiday defined in this test
*/
public function HolidayDataProvider()
{
$data = [];

for ($y = 0; $y < 50; $y++) {
$year = $this->generateRandomYear();
$date = new DateTime("$year-12-26", new DateTimeZone(self::TIMEZONE));

if (in_array($date->format('w'), [0, 6])) {
$date->add(new DateInterval('P2D'));
}

$data[] = [$year, $date->format('Y-m-d')];
}

return $data;
}

/**
* Tests the translated name of the holiday defined in this test.
*/
public function testTranslation()
{
$this->assertTranslatedHolidayName(self::REGION, self::HOLIDAY, $this->generateRandomYear(),
[self::LOCALE => 'Boxing Day']);
}

/**
* Tests type of the holiday defined in this test.
*/
public function testHolidayType()
{
$this->assertHolidayType(self::REGION, self::HOLIDAY, $this->generateRandomYear(), Holiday::TYPE_BANK);
}
}
84 changes: 84 additions & 0 deletions tests/UnitedKingdom/ChristmasDayTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<?php
/**
* This file is part of the Yasumi package.
*
* Copyright (c) 2015 - 2016 AzuyaLabs
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @author Sacha Telgenhof <stelgenhof@gmail.com>
*/

namespace Yasumi\tests\UnitedKingdom;

use DateInterval;
use DateTime;
use DateTimeZone;
use Yasumi\Holiday;
use Yasumi\tests\YasumiTestCaseInterface;

/**
* Class for testing Christmas Day in the United Kingdom.
*/
class ChristmasDayTest extends UnitedKingdomBaseTestCase implements YasumiTestCaseInterface
{
/**
* The name of the holiday
*/
const HOLIDAY = 'christmasDay';

/**
* 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 string $expected the expected date
*/
public function testHoliday($year, $expected)
{
$this->assertHoliday(self::REGION, self::HOLIDAY, $year,
new DateTime($expected, new DateTimeZone(self::TIMEZONE)));
}

/**
* Returns a list of test dates
*
* @return array list of test dates for the holiday defined in this test
*/
public function HolidayDataProvider()
{
$data = [];

for ($y = 0; $y < 50; $y++) {
$year = $this->generateRandomYear();
$date = new DateTime("$year-12-25", new DateTimeZone(self::TIMEZONE));

if (in_array($date->format('w'), [0, 6])) {
$date->add(new DateInterval('P2D'));
}

$data[] = [$year, $date->format('Y-m-d')];
}

return $data;
}

/**
* Tests the translated name of the holiday defined in this test.
*/
public function testTranslation()
{
$this->assertTranslatedHolidayName(self::REGION, self::HOLIDAY, $this->generateRandomYear(),
[self::LOCALE => 'Christmas Day']);
}

/**
* Tests type of the holiday defined in this test.
*/
public function testHolidayType()
{
$this->assertHolidayType(self::REGION, self::HOLIDAY, $this->generateRandomYear(), Holiday::TYPE_NATIONAL);
}
}

0 comments on commit c33dcc1

Please sign in to comment.