From 1c2af9d1824061e30352e3c476797435cb96c967 Mon Sep 17 00:00:00 2001 From: Brent Roose Date: Fri, 19 Apr 2019 10:50:08 +0200 Subject: [PATCH] Add period collection intersect --- CHANGELOG.md | 4 ++++ src/Period.php | 10 ++++++++++ src/PeriodCollection.php | 17 +++++++++++++++++ tests/PeriodCollectionTest.php | 32 ++++++++++++++++++++++++++++++++ 4 files changed, 63 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a4754a..0c7d788 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ All notable changes to `period` will be documented in this file +## 1.2.0 - 2019-04-19 + +- Add period collection intersect + ## 1.1.3 - 2019-04-05 - Even better docblock support for static return types diff --git a/src/Period.php b/src/Period.php index e77dbbb..d8fd320 100644 --- a/src/Period.php +++ b/src/Period.php @@ -437,6 +437,16 @@ public function diff(Period ...$periods): PeriodCollection return $collection; } + /** + * @param \Spatie\Period\Period $period + * + * @return static + */ + public function intersect(Period $period): Period + { + + } + public function getPrecisionMask(): int { return $this->precisionMask; diff --git a/src/PeriodCollection.php b/src/PeriodCollection.php index d6475e0..924b49b 100644 --- a/src/PeriodCollection.php +++ b/src/PeriodCollection.php @@ -91,6 +91,23 @@ public function gaps(): PeriodCollection return $boundaries->diff(...$this); } + public function intersect(Period $intersection): PeriodCollection + { + $intersected = new PeriodCollection(); + + foreach ($this as $period) { + $overlap = $intersection->overlapSingle($period); + + if ($overlap === null) { + continue; + } + + $intersected[] = $overlap; + } + + return $intersected; + } + public function isEmpty(): bool { return count($this->periods) === 0; diff --git a/tests/PeriodCollectionTest.php b/tests/PeriodCollectionTest.php index bc99dbf..3d23fdf 100644 --- a/tests/PeriodCollectionTest.php +++ b/tests/PeriodCollectionTest.php @@ -141,4 +141,36 @@ public function it_can_determine_whether_a_period_has_a_date() $this->assertFalse($period->contains(new DateTimeImmutable('2017-12-31'))); $this->assertFalse($period->contains(new DateTimeImmutable('2018-02-01'))); } + + /** + * @test + * + * A [========================] + * B [================] + * C [=====================] + * D [=====] + * + * LIMIT [===============] + * + * A [===============] + * B [========] + * C [=======] + */ + public function intersect_test() + { + $collection = new PeriodCollection( + Period::make('2019-01-05', '2019-01-15'), + Period::make('2019-01-01', '2019-01-10'), + Period::make('2019-01-10', '2019-01-15'), + Period::make('2019-02-01', '2019-02-15'), + ); + + $intersect = $collection->intersect(Period::make('2019-01-09', '2019-01-11')); + + $this->assertCount(3, $intersect); + + $this->assertTrue($intersect[0]->equals(Period::make('2019-01-09', '2019-01-11'))); + $this->assertTrue($intersect[1]->equals(Period::make('2019-01-09', '2019-01-10'))); + $this->assertTrue($intersect[2]->equals(Period::make('2019-01-10', '2019-01-11'))); + } }