Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add 'on' filter #119

Merged
merged 1 commit into from
Nov 22, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 75 additions & 0 deletions src/Yasumi/Filters/OnFilter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?php

/**
* This file is part of the Yasumi package.
*
* Copyright (c) 2015 - 2018 AzuyaLabs
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @author Clark Seanor <[email protected]>
* @author Sacha Telgenhof <[email protected]>
*/

namespace Yasumi\Filters;

use Countable;
use FilterIterator;
use Iterator;

/**
* OnFilter is a class used for filtering holidays based on a given date.
*
* Filters for all holidays that happen on the given date.
*
* Note: this class can be used separately, however is implemented by the AbstractProvider::on method.
*
* @package Yasumi\Filters
*/
class OnFilter extends FilterIterator implements Countable
{
/**
* @var string date to check for holidays
*/
private $date;


/**
* Construct the On FilterIterator Object
*
* @param \Iterator $iterator Iterator object of the Holidays Provider
* @param \DateTimeInterface $date Start date of the time frame to check against
*/

public function __construct(
Iterator $iterator,
\DateTimeInterface $date
) {
parent::__construct($iterator);
$this->date = $date->format('Y-m-d');
}

/**
* @return bool Check whether the current element of the iterator is acceptable
*/
public function accept(): bool
{
$holiday = $this->getInnerIterator()->current()->format('Y-m-d');
return $holiday == $this->date;
}

/**
* @return integer Returns the number of holidays that happen on the specified date
*/
public function count(): int
{
$days = \array_keys(\iterator_to_array($this));

\array_walk($days, function (&$day) {
$day = \str_replace('substituteHoliday:', '', $day);
});

return \count(\array_unique($days));
}
}
20 changes: 20 additions & 0 deletions src/Yasumi/Provider/AbstractProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
use InvalidArgumentException;
use IteratorAggregate;
use Yasumi\Filters\BetweenFilter;
use Yasumi\Filters\OnFilter;
use Yasumi\Holiday;
use Yasumi\ProviderInterface;
use Yasumi\TranslationsInterface;
Expand Down Expand Up @@ -443,6 +444,25 @@ public function between(\DateTimeInterface $start_date, \DateTimeInterface $end_
return new BetweenFilter($this->getIterator(), $start_date, $end_date, $equals);
}


/**
* Retrieves a list of all holidays that happen on the given date.
*
* Yasumi only calculates holidays for a single year, so a date outside of the given year will not appear to
* contain any holidays.
*
* Please take care to use the appropriate timezone for the date parameters. If there is a different timezone used
* for these parameters versus the instantiated Holiday Provider, the outcome might be unexpected (but correct).
*
* @param \DateTimeInterface $date Date to check for holidays on.
*
* @return \Yasumi\Filters\OnFilter
*/
public function on(\DateTimeInterface $date): OnFilter
{
return new OnFilter($this->getIterator(), $date);
}

/**
* Get an iterator for the holidays.
*
Expand Down
92 changes: 92 additions & 0 deletions tests/Base/HolidayOnFilterTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<?php
/**
* This file is part of the Yasumi package.
*
* Copyright (c) 2015 - 2018 AzuyaLabs
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @author Clark Seanor <[email protected]>
* @author Sacha Telgenhof <[email protected]>
*/

namespace Yasumi\tests\Base;

use DateTime;
use DateTimeZone;
use InvalidArgumentException;
use PHPUnit\Framework\TestCase;
use Yasumi\tests\YasumiBase;
use Yasumi\Yasumi;

/**
* Class HolidayOnFilterTest.
*
* Contains tests for testing the OnFilter class
*/
class HolidayOnFilterTest extends TestCase
{
use YasumiBase;

/**
* Tests the basic usage of the OnFilter.
*/
public function testHolidaysOnDate()
{
$timezone = 'Europe/Amsterdam';
$holidays = Yasumi::create('Netherlands', 2016);

$holidayDates = [
'goodFriday' => new DateTime('03/25/2016', new DateTimeZone($timezone)),
'easter' => new DateTime('03/27/2016', new DateTimeZone($timezone)),
'summerTime' => new DateTime('03/27/2016', new DateTimeZone($timezone))
];

foreach ($holidayDates as $name => $date) {
$holidaysOnDate = $holidays->on(
$date
);

$this->assertArrayHasKey($name, \iterator_to_array($holidaysOnDate));
}
}

public function testHolidaysNotOnDate()
{
$timezone = 'Europe/Amsterdam';
$holidays = Yasumi::create('Netherlands', 2016);

$holidayWrongDates = [
'goodFriday' => new DateTime('04/25/2016', new DateTimeZone($timezone)),
'easter' => new DateTime('03/22/2016', new DateTimeZone($timezone)),
'summerTime' => new DateTime('12/27/2016', new DateTimeZone($timezone))
];

foreach ($holidayWrongDates as $name => $date) {
$holidaysOnDate = $holidays->on(
$date
);

$this->assertArrayNotHasKey($name, \iterator_to_array($holidaysOnDate));
}
}

public function testCorrectNumberOfHolidaysOnDate()
{
$timezone = 'Europe/Amsterdam';
$holidays = Yasumi::create('Netherlands', 2016);

// No holidays
$holidaysOnDate = $holidays->on(new \DateTime('11/19/2016', new DateTimeZone($timezone)));
$this->assertEquals(0, $holidaysOnDate->count());

// One holiday
$holidaysOnDate = $holidays->on(new \DateTime('12/25/2016', new DateTimeZone($timezone)));
$this->assertEquals(1, $holidaysOnDate->count());

// Multiple holidays
$holidaysOnDate = $holidays->on(new \DateTime('03/27/2016', new DateTimeZone($timezone)));
$this->assertGreaterThan(1, $holidaysOnDate->count());
}
}