Skip to content

Commit

Permalink
Australian Public Holidays (#112)
Browse files Browse the repository at this point in the history
Proper handling for (just about) all public holidays in every Australian state and territory.
  • Loading branch information
Milamber33 authored and stelgenhof committed Jun 26, 2018
1 parent b5873d8 commit bc1b690
Show file tree
Hide file tree
Showing 242 changed files with 9,868 additions and 167 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
## [Unreleased]

### Added
- Holiday Providers for all Australian states and teritories. [\#112](https:/azuyalabs/yasumi/pull/112) ([Milamber33](https:/Milamber33))
- Added Reformation Day as offical holiday since 2018 in Schleswig-Holstein (Germany). [#106](https:/azuyalabs/yasumi/pull/106)
- Added Day of Reformation as offical holiday since 2018 in Hamburg (Germany). [#108](https:/azuyalabs/yasumi/pull/108)

Expand Down
115 changes: 46 additions & 69 deletions src/Yasumi/Provider/Australia.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
* file that was distributed with this source code.
*
* @author Sacha Telgenhof <[email protected]>
* @author William Sanders <[email protected]>
*/

namespace Yasumi\Provider;
Expand Down Expand Up @@ -35,16 +36,15 @@ class Australia extends AbstractProvider
/**
* Initialize holidays for Australia.
*
* @throws \Yasumi\Exception\InvalidDateException
* @throws \InvalidArgumentException
* @throws \Yasumi\Exception\UnknownLocaleException
* @throws \Exception
*/
public function initialize()
{
// Official Holidays
$this->calculateAustraliaDay();
$this->calculateNewYearHolidays();
$this->calculateAustraliaDay();
$this->calculateAnzacDay();

// Add Christian holidays
Expand All @@ -67,7 +67,6 @@ public function initialize()
* @link https://en.wikipedia.org/wiki/Waitangi_Day
* @link https://www.timeanddate.com/holidays/australia/australia-day
*
* @throws \Yasumi\Exception\InvalidDateException
* @throws \InvalidArgumentException
* @throws \Yasumi\Exception\UnknownLocaleException
* @throws \Exception
Expand All @@ -76,17 +75,18 @@ public function calculateAustraliaDay()
{
$date = new DateTime("$this->year-01-26", new DateTimeZone($this->timezone));

$this->calculateHoliday('australiaDay', [], $date);
$this->calculateHoliday('australiaDay', ['en_AU' => 'Australia Day'], $date);
}

/**
* Function to simplify moving holidays to mondays if required
*
* @param string $shortName
* @param array $names
* @param \DateTime $date
* @param DateTime $date
* @param bool $moveFromSaturday
* @param bool $moveFromSunday
* @param string $type
*
* @throws \Yasumi\Exception\InvalidDateException
* @throws \InvalidArgumentException
Expand All @@ -96,53 +96,61 @@ public function calculateAustraliaDay()
public function calculateHoliday(
string $shortName,
array $names = [],
\DateTime $date,
bool $moveFromSaturday = true,
bool $moveFromSunday = true
$date,
$moveFromSaturday = true,
$moveFromSunday = true,
$type = Holiday::TYPE_OFFICIAL
) {
$day = (int)$date->format('w');
if (($day === 0 && $moveFromSunday) || ($day === 6 && $moveFromSaturday)) {
$date = $date->add($day === 0 ? new DateInterval('P1D') : new DateInterval('P2D'));
}

$this->addHoliday(new Holiday($shortName, $names, $date, $this->locale));
$this->addHoliday(new Holiday($shortName, $names, $date, $this->locale, $type));
}

/**
* Holidays associated with the start of the modern Gregorian calendar.
*
* New Year's Day is on January 1 and is the first day of a new year in the Gregorian calendar,
* which is used in Australia and many other countries. Due to its geographical position close
* to the International Date Line, Australia is one of the first countries in the world to
* welcome the New Year.
* to the International Date Line, Australia is one of the first countries in the world to welcome the New Year.
* If it falls on a weekend an additional public holiday is held on the next available weekday.
*
* @link https://www.timeanddate.com/holidays/australia/new-year-day
*
* @throws \Yasumi\Exception\InvalidDateException
* @throws \InvalidArgumentException
* @throws \Yasumi\Exception\UnknownLocaleException
* @throws \Exception
*/
public function calculateNewYearHolidays()
{
$this->calculateHoliday(
'newYearsDay',
[],
new DateTime("$this->year-01-01", new DateTimeZone($this->timezone))
);
$newyearsday = new DateTime("$this->year-01-01", new DateTimeZone($this->timezone));
$this->calculateHoliday('newYearsDay', ['en_AU' => 'New Year\'s Day'], $newyearsday, false, false);
switch ($newyearsday->format('w')) {
case 0: // sunday
$newyearsday->add(new DateInterval('P1D'));
$this->calculateHoliday('newYearsHoliday', ['en_AU' => 'New Year\'s Holiday'], $newyearsday, false, false);
break;
case 6: // saturday
$newyearsday->add(new DateInterval('P2D'));
$this->calculateHoliday('newYearsHoliday', ['en_AU' => 'New Year\'s Holiday'], $newyearsday, false, false);
break;
}
}

/**
* ANZAC Day.
*
* Anzac Day is a national day of remembrance in Australia and New Zealand that broadly commemorates all Australians
* and New Zealanders "who served and died in all wars, conflicts, and peacekeeping operations"
* Observed on 25 April each year.
* Observed on 25 April each year. Unlike most other Australian public holidays, If it falls on a weekend it is NOT moved
* to the next available weekday, nor is there an additional public holiday held. However, if it clashes with Easter,
* an additional public holiday is held for Easter.
*
* @link https://en.wikipedia.org/wiki/Anzac_Day
* @link https://www.timeanddate.com/holidays/australia/anzac-day
*
* @throws \Yasumi\Exception\InvalidDateException
* @throws \InvalidArgumentException
* @throws \Yasumi\Exception\UnknownLocaleException
* @throws \Exception
Expand All @@ -154,19 +162,24 @@ public function calculateAnzacDay()
}

$date = new DateTime("$this->year-04-25", new DateTimeZone($this->timezone));

$this->calculateHoliday('anzacDay', [], $date);
$this->calculateHoliday('anzacDay', ['en_AU' => 'ANZAC Day'], $date, false, false);
$easter = $this->calculateEaster($this->year, $this->timezone);
$easterMonday = $this->calculateEaster($this->year, $this->timezone);
$easterMonday->add(new DateInterval('P1D'));
if (($date->format('Y-m-d') === $easter->format('Y-m-d')) || ($date->format('Y-m-d') === $easterMonday->format('Y-m-d'))) {
$easterMonday->add(new DateInterval('P1D'));
$this->calculateHoliday('easterTuesday', ['en_AU' => 'Easter Tuesday'], $easterMonday, false, false);
}
}

/**
* Christmas Day / Boxing Day.
*
* Christmas day, and Boxing day are public holidays in Australia,
* if they fall on the weekend they are moved to the next available weekday.
* if they fall on the weekend an additional public holiday is held on the next available weekday.
*
* @link https://www.timeanddate.com/holidays/australia/christmas-day-holiday
*
* @throws \Yasumi\Exception\InvalidDateException
* @throws \InvalidArgumentException
* @throws \Yasumi\Exception\UnknownLocaleException
* @throws \Exception
Expand All @@ -175,60 +188,24 @@ public function calculateChristmasDay()
{
$christmasDay = new DateTime("$this->year-12-25", new DateTimeZone($this->timezone));
$boxingDay = new DateTime("$this->year-12-26", new DateTimeZone($this->timezone));
$this->calculateHoliday('christmasDay', ['en_AU' => 'Christmas Day'], $christmasDay, false, false);
$this->calculateHoliday('secondChristmasDay', ['en_AU' => 'Boxing Day'], $boxingDay, false, false);

switch ($christmasDay->format('w')) {
case 0: // sunday
$christmasDay->add(new \DateInterval('P2D'));
$christmasDay->add(new DateInterval('P2D'));
$this->calculateHoliday('christmasHoliday', ['en_AU' => 'Christmas Holiday'], $christmasDay, false, false);
break;
case 5: // friday
$boxingDay->add(new \DateInterval('P2D'));
$boxingDay->add(new DateInterval('P2D'));
$this->calculateHoliday('secondChristmasHoliday', ['en_AU' => 'Boxing Day Holiday'], $boxingDay, false, false);
break;
case 6: // saturday
$christmasDay->add(new \DateInterval('P2D'));
$boxingDay->add(new \DateInterval('P2D'));
$christmasDay->add(new DateInterval('P2D'));
$boxingDay->add(new DateInterval('P2D'));
$this->calculateHoliday('christmasHoliday', ['en_AU' => 'Christmas Holiday'], $christmasDay, false, false);
$this->calculateHoliday('secondChristmasHoliday', ['en_AU' => 'Boxing Day Holiday'], $boxingDay, false, false);
break;
}
$this->calculateHoliday('christmasDay', [], $christmasDay);
$this->calculateHoliday('secondChristmasDay', [], $boxingDay);
}

/**
* Queens Birthday.
*
* The Queen's Birthday is an Australian public holiday but the date varies across
* states and territories. Australia celebrates this holiday because it is a constitutional
* monarchy, with the English monarch as head of state.
*
* Her actual birthday is on April 21, but it's celebrated as a public holiday on the second Monday of June.
* (Except QLD & WA)
*
* @link https://www.timeanddate.com/holidays/australia/queens-birthday
*
* @throws \InvalidArgumentException
* @throws \Exception
*/
public function calculateQueensBirthday()
{
$this->calculateHoliday(
'queensBirthday',
['en_AU' => 'Queens Birthday'],
new DateTime('second monday of june ' . $this->year, new DateTimeZone($this->timezone)),
false,
false
);
}

/**
* @link https://www.timeanddate.com/holidays/australia/labour-day
*
* @throws \Yasumi\Exception\InvalidDateException
* @throws \InvalidArgumentException
* @throws \Yasumi\Exception\UnknownLocaleException
*/
public function calculateLabourDay()
{
$date = new DateTime('first Monday in October' . " $this->year", new DateTimeZone($this->timezone));

$this->addHoliday(new Holiday('labourDay', [], $date, $this->locale));
}
}
Loading

0 comments on commit bc1b690

Please sign in to comment.