Skip to content

Commit

Permalink
Allow followups to define the skipped days
Browse files Browse the repository at this point in the history
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
  • Loading branch information
heiglandreas committed Oct 15, 2019
1 parent 572a68f commit 39b5ebb
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 13 deletions.
4 changes: 4 additions & 0 deletions share/holidays.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
<xs:enumeration value="saturday"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="daynamelist">
<xs:list itemType="daynames" />
</xs:simpleType>
<xs:simpleType name="calendars">
<xs:restriction base="xs:string">
<xs:enumeration value="buddhist"/>
Expand Down Expand Up @@ -57,6 +60,7 @@
<xs:attribute name="day" type="dayInt" use="required"/>
<xs:attribute name="month" type="monthInt" use="required"/>
<xs:attribute name="followup" type="daynames" use="required" />
<xs:attribute name="replaced" type="daynamelist" use="optional" />
<xs:attribute name="free" type="xs:boolean" use="required"/>
<xs:attribute name="comment" type="xs:string"/>
<xs:attribute name="calendar" type="calendars"/>
Expand Down
4 changes: 3 additions & 1 deletion src/HolidayIteratorFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down Expand Up @@ -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(
Expand Down
39 changes: 32 additions & 7 deletions src/IteratorItem/DateFollowUp.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand All @@ -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);
}
}
47 changes: 42 additions & 5 deletions tests/IteratorItem/DateFollowUpTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand All @@ -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
],
];
}
}

0 comments on commit 39b5ebb

Please sign in to comment.