From 39b5ebbbb31a4bbf604fd8239dd6db60d5bc8570 Mon Sep 17 00:00:00 2001 From: Andreas Heigl Date: Tue, 15 Oct 2019 20:24:52 +0200 Subject: [PATCH] Allow followups to define the skipped days This addition allows to configure which days shall be skipped in the gregorian calendar if the holyday falls onto one. By default this is saturday and sunday but one can now also only define one or multiple days. Thanks to Sarel van der Walt for the input for that --- share/holidays.xsd | 4 +++ src/HolidayIteratorFactory.php | 4 ++- src/IteratorItem/DateFollowUp.php | 39 ++++++++++++++++---- tests/IteratorItem/DateFollowUpTest.php | 47 ++++++++++++++++++++++--- 4 files changed, 81 insertions(+), 13 deletions(-) diff --git a/share/holidays.xsd b/share/holidays.xsd index bf01b89..b388fb2 100644 --- a/share/holidays.xsd +++ b/share/holidays.xsd @@ -26,6 +26,9 @@ + + + @@ -57,6 +60,7 @@ + diff --git a/src/HolidayIteratorFactory.php b/src/HolidayIteratorFactory.php index 3082dc9..75167f2 100644 --- a/src/HolidayIteratorFactory.php +++ b/src/HolidayIteratorFactory.php @@ -34,6 +34,7 @@ use Org_Heigl\Holidaychecker\IteratorItem\Easter; use Org_Heigl\Holidaychecker\IteratorItem\EasterOrthodox; use Org_Heigl\Holidaychecker\IteratorItem\Relative; +use function explode; class HolidayIteratorFactory { @@ -131,7 +132,8 @@ private function getElement(\DOMElement $child) : HolidayIteratorItemInterface $child->textContent, $this->getFree($child), $day, - $child->getAttribute('followup') + $child->getAttribute('followup'), + ($child->hasAttribute('replaced')?explode(' ', $child->getAttribute('replaced')):[]) ); case 'relative': return new Relative( diff --git a/src/IteratorItem/DateFollowUp.php b/src/IteratorItem/DateFollowUp.php index 86a0d50..bf46d89 100644 --- a/src/IteratorItem/DateFollowUp.php +++ b/src/IteratorItem/DateFollowUp.php @@ -43,24 +43,22 @@ class DateFollowUp implements HolidayIteratorItemInterface private $followup; - public function __construct(string $name, bool $holiday, CalendarDay $day, string $followup) + private $replaced; + + public function __construct(string $name, bool $holiday, CalendarDay $day, string $followup, array $replaced = []) { $this->day = $day; $this->followup = $followup; $this->holiday = $holiday; $this->name = $name; + $this->replaced = $this->replacedDays($replaced); } public function dateMatches(\DateTimeInterface $date) : bool { $weekday = $this->day->getWeekdayForGregorianYear($date->format('Y')); - $days = [ - IntlCalendar::DOW_SATURDAY, - IntlCalendar::DOW_SUNDAY, - ]; - - if (in_array($weekday, $days)) { + if (in_array($weekday, $this->replaced)) { return $this->day->isFollowUpDay($date, $this->followup); } @@ -76,4 +74,31 @@ public function isHoliday(): bool { return $this->holiday; } + + private static function replacedDays(array $replaced): array + { + $daymap = [ + 'sunday' => IntlCalendar::DOW_SUNDAY, + 'monday' => IntlCalendar::DOW_MONDAY, + 'tuesday' => IntlCalendar::DOW_TUESDAY, + 'wednesday' => IntlCalendar::DOW_WEDNESDAY, + 'thursday' => IntlCalendar::DOW_THURSDAY, + 'friday' => IntlCalendar::DOW_FRIDAY, + 'saturday' => IntlCalendar::DOW_SATURDAY, + ]; + + if ([] === $replaced) { + return [ + IntlCalendar::DOW_SATURDAY, + IntlCalendar::DOW_SUNDAY, + ]; + } + + return array_map(function ($day) use ($daymap) { + if (! isset($daymap[$day])) { + return null; + } + return $daymap[$day]; + }, $replaced); + } } diff --git a/tests/IteratorItem/DateFollowUpTest.php b/tests/IteratorItem/DateFollowUpTest.php index 1e11003..8bd4ecc 100644 --- a/tests/IteratorItem/DateFollowUpTest.php +++ b/tests/IteratorItem/DateFollowUpTest.php @@ -44,11 +44,19 @@ class DateFollowUpTest extends TestCase * @covers \Org_Heigl\Holidaychecker\IteratorItem\DateFollowUp::__construct * @covers \Org_Heigl\Holidaychecker\IteratorItem\DateFollowUp::dateMatches */ - public function testThatDateFollowupTestWorks($dateTime, $day, $month, $followup, $result, $name, $isHoliday) - { + public function testThatDateFollowupTestWorks( + $dateTime, + $day, + $month, + $followup, + $replaced, + $result, + $name, + $isHoliday + ) { $calendarDate = CalendarDayFactory::createCalendarDay($day, $month, Calendar::GREGORIAN); - $followUp = new DateFollowUp($name, $isHoliday, $calendarDate, $followup); + $followUp = new DateFollowUp($name, $isHoliday, $calendarDate, $followup, $replaced); $this->assertEquals($result, $followUp->dateMatches($dateTime)); $this->assertEquals($name, $followUp->getName()); $this->assertEquals($isHoliday, $followUp->isHoliday()); @@ -57,8 +65,37 @@ public function testThatDateFollowupTestWorks($dateTime, $day, $month, $followup public function dateProvider() { return [ - [new \DateTimeImmutable('2018-03-01 12:00:00+00:00'), 25, 2, 'thursday', true, 'test', true], - [new \DateTimeImmutable('2018-02-26 12:00:00+00:00'), 24, 2, 'monday', true, 'test', true], + [new \DateTimeImmutable('2018-03-01 12:00:00+00:00'), 25, 2, 'thursday', [], true, 'test', true], + [new \DateTimeImmutable('2018-02-26 12:00:00+00:00'), 24, 2, 'monday', [], true, 'test', true], + // [new \DateTimeImmutable('2019-01-01 12:00:00+00:00'), 30, 12, 'tuesday', [], true, 'test', true], + [ + new \DateTimeImmutable('2019-10-12 12:00:00+00:00'), + 11, + 10, + 'saturday', + ['thursday', 'friday'], + true, + 'test', + true + ], [ + new \DateTimeImmutable('2019-10-12 12:00:00+00:00'), + 10, + 10, + 'saturday', + ['thursday', 'friday'], + true, + 'test', + true + ], [ + new \DateTimeImmutable('2019-10-09 12:00:00+00:00'), + 9, + 10, + 'saturday', + ['thursday', 'friday'], + true, + 'test', + true + ], ]; } }