Skip to content

Commit 1a235e3

Browse files
authored
Implement initial date range (#1)
1 parent 8153427 commit 1a235e3

File tree

8 files changed

+753
-0
lines changed

8 files changed

+753
-0
lines changed

src/DateRange.php

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
<?php
2+
/**
3+
* This file is part of Zee Project.
4+
*
5+
* For the full copyright and license information, please view the LICENSE
6+
* file that was distributed with this source code.
7+
*
8+
* @see https://github.com/zee/
9+
*/
10+
11+
namespace Zee\DateRange;
12+
13+
use DateTimeImmutable;
14+
use DateTimeInterface;
15+
16+
/**
17+
* Date range implementation.
18+
*/
19+
final class DateRange implements DateRangeInterface
20+
{
21+
/**
22+
* @var DateTimeInterface
23+
*/
24+
private $begin;
25+
26+
/**
27+
* @var DateTimeInterface
28+
*/
29+
private $end;
30+
31+
/**
32+
* @param DateTimeInterface $begin
33+
* @param DateTimeInterface $end
34+
*/
35+
public function __construct(DateTimeInterface $begin, DateTimeInterface $end = null)
36+
{
37+
$this->guardDateSequence($begin, $end);
38+
39+
$this->begin = $begin;
40+
$this->end = $end;
41+
}
42+
43+
/**
44+
* {@inheritdoc}
45+
*/
46+
public function getBegin(): DateTimeInterface
47+
{
48+
return $this->begin;
49+
}
50+
51+
/**
52+
* {@inheritdoc}
53+
*/
54+
public function getEnd(): DateTimeInterface
55+
{
56+
return $this->end;
57+
}
58+
59+
/**
60+
* {@inheritdoc}
61+
*/
62+
public function isFinite(): bool
63+
{
64+
return $this->end instanceof DateTimeInterface;
65+
}
66+
67+
/**
68+
* {@inheritdoc}
69+
*/
70+
public function isBeginAt(DateTimeInterface $time): bool
71+
{
72+
return $this->begin->getTimestamp() === $time->getTimestamp();
73+
}
74+
75+
/**
76+
* {@inheritdoc}
77+
*/
78+
public function isEndAt(DateTimeInterface $time): bool
79+
{
80+
return $this->end->getTimestamp() === $time->getTimestamp();
81+
}
82+
83+
/**
84+
* {@inheritdoc}
85+
*/
86+
public function isStarted(): bool
87+
{
88+
return $this->begin <= new DateTimeImmutable();
89+
}
90+
91+
/**
92+
* {@inheritdoc}
93+
*/
94+
public function isEnded(): bool
95+
{
96+
return $this->isFinite() && $this->end <= new DateTimeImmutable();
97+
}
98+
99+
/**
100+
* {@inheritdoc}
101+
*/
102+
public function beginAt(DateTimeInterface $time): DateRangeInterface
103+
{
104+
$this->guardDateSequence($time, $this->end);
105+
106+
$this->begin = $time;
107+
108+
return $this;
109+
}
110+
111+
/**
112+
* {@inheritdoc}
113+
*/
114+
public function endAt(DateTimeInterface $time): DateRangeInterface
115+
{
116+
$this->guardDateSequence($this->begin, $time);
117+
118+
$this->end = $time;
119+
120+
return $this;
121+
}
122+
123+
/**
124+
* @param DateTimeInterface $begin
125+
* @param DateTimeInterface|null $end
126+
*/
127+
private function guardDateSequence(DateTimeInterface $begin, DateTimeInterface $end = null)
128+
{
129+
if ($end && $end <= $begin) {
130+
throw new DateRangeException('Invalid end, must be after begin');
131+
}
132+
}
133+
}

src/DateRangeException.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
/**
3+
* This file is part of Zee Project.
4+
*
5+
* For the full copyright and license information, please view the LICENSE
6+
* file that was distributed with this source code.
7+
*
8+
* @see https://github.com/zee/
9+
*/
10+
11+
namespace Zee\DateRange;
12+
13+
use DomainException;
14+
use Throwable;
15+
16+
/**
17+
* Date range exception.
18+
*/
19+
final class DateRangeException extends DomainException
20+
{
21+
/**
22+
* @param string $message
23+
* @param Throwable|null $previous
24+
*/
25+
public function __construct(string $message = 'Invalid data range', Throwable $previous = null)
26+
{
27+
parent::__construct($message, 0, $previous);
28+
}
29+
}

src/DateRangeImmutable.php

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
<?php
2+
/**
3+
* This file is part of Zee Project.
4+
*
5+
* For the full copyright and license information, please view the LICENSE
6+
* file that was distributed with this source code.
7+
*
8+
* @see https://github.com/zee/
9+
*/
10+
11+
namespace Zee\DateRange;
12+
13+
use DateTimeInterface;
14+
15+
/**
16+
* Immutable implementation of date range.
17+
*
18+
* This class behaves the same as `{@see DateRange}`
19+
* except it never modifies itself but returns a new object instead.
20+
*/
21+
final class DateRangeImmutable implements DateRangeInterface
22+
{
23+
/**
24+
* @var DateRange
25+
*/
26+
private $storage;
27+
28+
/**
29+
* @param DateTimeInterface $begin
30+
* @param DateTimeInterface $end
31+
*/
32+
public function __construct(DateTimeInterface $begin, DateTimeInterface $end = null)
33+
{
34+
$this->storage = new DateRange($begin, $end);
35+
}
36+
37+
/**
38+
* Clones internal storage.
39+
*/
40+
public function __clone()
41+
{
42+
$this->storage = clone $this->storage;
43+
}
44+
45+
/**
46+
* {@inheritdoc}
47+
*/
48+
public function getBegin(): DateTimeInterface
49+
{
50+
return $this->storage->getBegin();
51+
}
52+
53+
/**
54+
* {@inheritdoc}
55+
*/
56+
public function getEnd(): DateTimeInterface
57+
{
58+
return $this->storage->getEnd();
59+
}
60+
61+
/**
62+
* {@inheritdoc}
63+
*/
64+
public function isFinite(): bool
65+
{
66+
return $this->storage->isFinite();
67+
}
68+
69+
/**
70+
* {@inheritdoc}
71+
*/
72+
public function isBeginAt(DateTimeInterface $time): bool
73+
{
74+
return $this->storage->isBeginAt($time);
75+
}
76+
77+
/**
78+
* {@inheritdoc}
79+
*/
80+
public function isEndAt(DateTimeInterface $time): bool
81+
{
82+
return $this->storage->isEndAt($time);
83+
}
84+
85+
/**
86+
* {@inheritdoc}
87+
*/
88+
public function isStarted(): bool
89+
{
90+
return $this->storage->isStarted();
91+
}
92+
93+
/**
94+
* {@inheritdoc}
95+
*/
96+
public function isEnded(): bool
97+
{
98+
return $this->storage->isEnded();
99+
}
100+
101+
/**
102+
* {@inheritdoc}
103+
*/
104+
public function beginAt(DateTimeInterface $time): DateRangeInterface
105+
{
106+
$clone = clone $this;
107+
$clone->storage->beginAt($time);
108+
109+
return $clone;
110+
}
111+
112+
/**
113+
* {@inheritdoc}
114+
*/
115+
public function endAt(DateTimeInterface $time): DateRangeInterface
116+
{
117+
$clone = clone $this;
118+
$clone->storage->endAt($time);
119+
120+
return $clone;
121+
}
122+
}

src/DateRangeInterface.php

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<?php
2+
/**
3+
* This file is part of Zee Project.
4+
*
5+
* For the full copyright and license information, please view the LICENSE
6+
* file that was distributed with this source code.
7+
*
8+
* @see https://github.com/zee/
9+
*/
10+
11+
namespace Zee\DateRange;
12+
13+
use DateTimeInterface;
14+
15+
/**
16+
* Date range interface.
17+
*/
18+
interface DateRangeInterface
19+
{
20+
/**
21+
* @return DateTimeInterface
22+
*/
23+
public function getBegin(): DateTimeInterface;
24+
25+
/**
26+
* @return DateTimeInterface
27+
*/
28+
public function getEnd(): DateTimeInterface;
29+
30+
/**
31+
* @return bool
32+
*/
33+
public function isFinite(): bool;
34+
35+
/**
36+
* @param DateTimeInterface $time
37+
*
38+
* @return bool
39+
*/
40+
public function isBeginAt(DateTimeInterface $time): bool;
41+
42+
/**
43+
* @param DateTimeInterface $time
44+
*
45+
* @return bool
46+
*/
47+
public function isEndAt(DateTimeInterface $time): bool;
48+
49+
/**
50+
* @return bool
51+
*/
52+
public function isStarted(): bool;
53+
54+
/**
55+
* @return bool
56+
*/
57+
public function isEnded(): bool;
58+
59+
/**
60+
* @param DateTimeInterface $time
61+
*
62+
* @return DateRangeInterface
63+
*/
64+
public function beginAt(DateTimeInterface $time): DateRangeInterface;
65+
66+
/**
67+
* @param DateTimeInterface $time
68+
*
69+
* @return DateRangeInterface
70+
*/
71+
public function endAt(DateTimeInterface $time): DateRangeInterface;
72+
}

0 commit comments

Comments
 (0)