1
|
|
|
<?php |
2
|
|
|
declare(strict_types=1); |
3
|
|
|
namespace Kreemers\Period; |
4
|
|
|
|
5
|
|
|
use DateInterval; |
6
|
|
|
use DateTime; |
7
|
|
|
use Kreemers\Period\Exception\EndBeforeStartException; |
8
|
|
|
|
9
|
|
|
final class GenericPeriod implements Period |
10
|
|
|
{ |
11
|
|
|
/** |
12
|
|
|
* @var DateTime |
13
|
|
|
*/ |
14
|
|
|
private $start; |
15
|
|
|
|
16
|
|
|
/** |
17
|
|
|
* @var DateTime |
18
|
|
|
*/ |
19
|
|
|
private $end; |
20
|
|
|
|
21
|
4 |
|
private function __construct( |
22
|
|
|
DateTime $start, |
23
|
|
|
DateTime $end |
24
|
|
|
) { |
25
|
4 |
|
if ($start > $end) { |
26
|
1 |
|
throw new EndBeforeStartException(); |
27
|
|
|
} |
28
|
|
|
|
29
|
3 |
|
$this->start = clone $start; |
30
|
3 |
|
$this->end = clone $end; |
31
|
3 |
|
} |
32
|
|
|
|
33
|
2 |
|
public static function create( |
34
|
|
|
DateTime $start, |
35
|
|
|
DateTime $end |
36
|
|
|
) { |
37
|
2 |
|
return new static( |
38
|
2 |
|
$start, |
39
|
|
|
$end |
40
|
|
|
); |
41
|
|
|
} |
42
|
|
|
|
43
|
1 |
|
public static function createDay( |
44
|
|
|
DateTime $day |
45
|
|
|
) { |
46
|
1 |
|
$start = (clone $day)->setTime(0, 0, 0); |
47
|
1 |
|
$end = (clone $day)->setTime(23, 59, 59); |
48
|
1 |
|
return new static($start, $end); |
|
|
|
|
49
|
|
|
} |
50
|
|
|
|
51
|
1 |
|
public static function createMonth( |
52
|
|
|
DateTime $month |
53
|
|
|
) { |
54
|
1 |
|
$start = (clone $month)->sub( |
55
|
1 |
|
DateInterval::createFromDateString(((int) $month->format('d') - 1) . ' days') |
56
|
|
|
); |
57
|
1 |
|
$end = (clone $start)->add( |
58
|
1 |
|
DateInterval::createFromDateString(((int) $month->format('t') - 1) . ' days') |
59
|
1 |
|
)->setTime(23, 59, 59); |
60
|
1 |
|
return new static($start, $end); |
|
|
|
|
61
|
|
|
} |
62
|
|
|
|
63
|
1 |
|
public function getStart(): DateTime |
64
|
|
|
{ |
65
|
1 |
|
return $this->start; |
66
|
|
|
} |
67
|
|
|
|
68
|
1 |
|
public function getEnd(): DateTime |
69
|
|
|
{ |
70
|
1 |
|
return $this->end; |
71
|
|
|
} |
72
|
|
|
|
73
|
3 |
|
public function equals(Period $period): bool |
74
|
|
|
{ |
75
|
3 |
|
return $this->getStart() == $period->getStart() |
76
|
3 |
|
&& $this->getEnd() == $period->getEnd(); |
77
|
|
|
} |
78
|
|
|
|
79
|
2 |
|
public function in(Period $period): bool |
80
|
|
|
{ |
81
|
2 |
|
if ($this->getStart() >= $period->getStart() |
82
|
2 |
|
&& $this->getStart() <= $period->getEnd() |
83
|
2 |
|
&& $this->getEnd() >= $period->getStart() |
84
|
2 |
|
&& $this->getEnd() <= $period->getEnd() |
85
|
|
|
) { |
86
|
1 |
|
return true; |
87
|
|
|
} |
88
|
|
|
|
89
|
1 |
|
return false; |
90
|
|
|
} |
91
|
|
|
|
92
|
2 |
|
public function encloses(Period $period): bool |
93
|
|
|
{ |
94
|
2 |
|
if ($this->getStart() <= $period->getStart() |
95
|
2 |
|
&& $this->getEnd() >= $period->getEnd() |
96
|
|
|
) { |
97
|
1 |
|
return true; |
98
|
|
|
} |
99
|
|
|
|
100
|
1 |
|
return false; |
101
|
|
|
} |
102
|
|
|
|
103
|
5 |
|
public function intersects(Period $period): bool |
104
|
|
|
{ |
105
|
5 |
|
if ($this->getStart() >= $period->getStart() |
106
|
5 |
|
&& $this->getStart() <= $period->getEnd() |
107
|
|
|
) { |
108
|
2 |
|
return true; |
109
|
|
|
} |
110
|
|
|
|
111
|
3 |
|
if ($this->getEnd() <= $period->getEnd() |
112
|
3 |
|
&& $this->getEnd() >= $period->getStart() |
113
|
|
|
) { |
114
|
1 |
|
return true; |
115
|
|
|
} |
116
|
|
|
|
117
|
2 |
|
if ($this->in($period) |
118
|
2 |
|
|| $this->encloses($period) |
119
|
|
|
) { |
120
|
1 |
|
return true; |
121
|
|
|
} |
122
|
|
|
|
123
|
1 |
|
return false; |
124
|
|
|
} |
125
|
|
|
} |