Skip to content

Commit 17e075a

Browse files
authored
Add more methods to DateRange (#9)
* Add date interval factory and date period factory * Add DateRange split * Adjust docs
1 parent c43687e commit 17e075a

File tree

3 files changed

+121
-0
lines changed

3 files changed

+121
-0
lines changed

src/DateRange.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,12 @@
1010

1111
namespace Zee\DateRange;
1212

13+
use DateInterval;
14+
use DatePeriod;
1315
use DateTimeImmutable;
1416
use DateTimeInterface;
1517
use JsonSerializable;
18+
use Traversable;
1619
use Zee\DateRange\States\RangeState;
1720
use Zee\DateRange\States\UndefinedRange;
1821

@@ -171,4 +174,37 @@ public function isEnded(): bool
171174
{
172175
return $this->hasEndTime() && $this->state->compareEndTime(new DateTimeImmutable()) < 0;
173176
}
177+
178+
/**
179+
* {@inheritdoc}
180+
*/
181+
public function getDateInterval(): DateInterval
182+
{
183+
return $this->getStartTime()->diff($this->getEndTime());
184+
}
185+
186+
/**
187+
* {@inheritdoc}
188+
*/
189+
public function getDatePeriod(DateInterval $interval, int $option = 0): DatePeriod
190+
{
191+
return new DatePeriod($this->getStartTime(), $interval, $this->getEndTime(), $option);
192+
}
193+
194+
/**
195+
* {@inheritdoc}
196+
*/
197+
public function split(DateInterval $interval): Traversable
198+
{
199+
$startDate = $this->getStartTime();
200+
$endDate = $this->getEndTime();
201+
$period = $this->getDatePeriod($interval, DatePeriod::EXCLUDE_START_DATE);
202+
203+
foreach ($period as $date) {
204+
yield new DateRange($startDate, $date);
205+
$startDate = $date;
206+
}
207+
208+
yield new DateRange($startDate, $endDate);
209+
}
174210
}

src/DateRangeInterface.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,10 @@
1010

1111
namespace Zee\DateRange;
1212

13+
use DateInterval;
14+
use DatePeriod;
1315
use DateTimeInterface;
16+
use Traversable;
1417

1518
/**
1619
* Date range interface.
@@ -101,4 +104,37 @@ public function isStarted(): bool;
101104
* @return bool
102105
*/
103106
public function isEnded(): bool;
107+
108+
/**
109+
* Returns the range interval.
110+
*
111+
* @return DateInterval
112+
*/
113+
public function getDateInterval(): DateInterval;
114+
115+
/**
116+
* Returns date period according to a given interval.
117+
*
118+
* Allows iteration over the range.
119+
*
120+
* @param DateInterval $interval
121+
* @param int $option
122+
*
123+
* @return DatePeriod|DateTimeInterface[]
124+
*/
125+
public function getDatePeriod(DateInterval $interval, int $option = 0): DatePeriod;
126+
127+
/**
128+
* Splits range into smaller ranges according to a given interval.
129+
*
130+
* All resulting ranges (except first and last) starts on same date as previously ends.
131+
* The first starts on same date as parent range, last ends on same date as parent range.
132+
*
133+
* Keep in mind that the last range may be equal or lesser than the given interval.
134+
*
135+
* @param DateInterval $interval
136+
*
137+
* @return Traversable
138+
*/
139+
public function split(DateInterval $interval): Traversable;
104140
}

tests/DateRangeTest.php

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
namespace Zee\DateRange;
1212

13+
use DateInterval;
1314
use DateTimeImmutable;
1415
use DateTimeZone;
1516
use DomainException;
@@ -279,4 +280,52 @@ public function dumpRange()
279280

280281
self::assertNotContains('state', $dump);
281282
}
283+
284+
/**
285+
* @test
286+
*/
287+
public function getDateInterval()
288+
{
289+
$yesterday = new DateTimeImmutable('-1 day');
290+
$tomorrow = new DateTimeImmutable('+1 day');
291+
$range = new DateRange($yesterday, $tomorrow);
292+
$interval = $range->getDateInterval();
293+
294+
self::assertSame(2, $interval->days);
295+
}
296+
297+
/**
298+
* @test
299+
*/
300+
public function getDatePeriod()
301+
{
302+
$yesterday = new DateTimeImmutable('-1 day');
303+
$tomorrow = new DateTimeImmutable('+1 day');
304+
$range = new DateRange($yesterday, $tomorrow);
305+
$interval = new DateInterval('P1D');
306+
$period = $range->getDatePeriod($interval);
307+
308+
self::assertSame($range->getStartTime()->getTimestamp(), $period->getStartDate()->getTimestamp());
309+
self::assertSame($range->getEndTime()->getTimestamp(), $period->getEndDate()->getTimestamp());
310+
self::assertSame(2, iterator_count($period));
311+
}
312+
313+
/**
314+
* @test
315+
*/
316+
public function splitRange()
317+
{
318+
$yesterday = new DateTimeImmutable('-1 day');
319+
$tomorrow = new DateTimeImmutable('+1 day');
320+
$range = new DateRange($yesterday, $tomorrow);
321+
$interval = new DateInterval('P1D');
322+
323+
$ranges = $range->split($interval);
324+
325+
self::assertSame(2, iterator_count($ranges));
326+
327+
foreach ($range->split($interval) as $range) {
328+
self::assertInstanceOf(DateRange::class, $range);
329+
}
330+
}
282331
}

0 commit comments

Comments
 (0)