10
10
11
11
namespace Zee \DateRange ;
12
12
13
- use DateTimeImmutable ;
14
13
use DateTimeInterface ;
15
14
use JsonSerializable ;
16
- use Serializable ;
15
+ use Zee \DateRange \States \RangeState ;
16
+ use Zee \DateRange \States \UndefinedRange ;
17
17
18
18
/**
19
- * Date range implementation .
19
+ * Implementation of date range value object .
20
20
*/
21
- final class DateRange implements DateRangeInterface, Serializable, JsonSerializable
21
+ final class DateRange implements DateRangeInterface, JsonSerializable
22
22
{
23
23
/**
24
- * @var DateTimeInterface
24
+ * @var RangeState
25
25
*/
26
- private $ begin ;
26
+ private $ state ;
27
27
28
28
/**
29
- * @var DateTimeInterface
29
+ * @param DateTimeInterface|null $startTime
30
+ * @param DateTimeInterface|null $endTime
30
31
*/
31
- private $ end ;
32
-
33
- /**
34
- * @param DateTimeInterface $begin
35
- * @param DateTimeInterface $end
36
- */
37
- public function __construct (DateTimeInterface $ begin , DateTimeInterface $ end = null )
32
+ public function __construct (DateTimeInterface $ startTime = null , DateTimeInterface $ endTime = null )
38
33
{
39
- $ this ->guardDateSequence ($ begin , $ end );
34
+ $ state = new UndefinedRange ();
35
+
36
+ if (isset ($ startTime )) {
37
+ $ state = $ state ->setStartTime ($ startTime );
38
+ }
39
+
40
+ if (isset ($ endTime )) {
41
+ $ state = $ state ->setEndTime ($ endTime );
42
+ }
40
43
41
- $ this ->begin = $ begin ;
42
- $ this ->end = $ end ;
44
+ $ this ->state = $ state ;
43
45
}
44
46
45
47
/**
48
+ * Returns string representation of range.
49
+ *
46
50
* {@inheritdoc}
47
51
*/
48
- public function __toString ()
52
+ public function __toString (): string
49
53
{
50
- return $ this ->serialize () ;
54
+ return ( string ) $ this ->state ;
51
55
}
52
56
53
57
/**
@@ -56,141 +60,110 @@ public function __toString()
56
60
public function __debugInfo ()
57
61
{
58
62
return [
59
- 'begin ' => $ this ->getBegin ()->format ('c ' ),
60
- 'end ' => $ this ->isFinite ()
61
- ? $ this ->getEnd ()->format ('c ' )
62
- : '- ' ,
63
+ 'startTime ' => $ this ->state ->hasStartTime ()
64
+ ? $ this ->state ->getStartTime ()
65
+ : null ,
66
+ 'endTime ' => $ this ->state ->hasEndTime ()
67
+ ? $ this ->state ->getEndTime ()
68
+ : null ,
63
69
];
64
70
}
65
71
66
72
/**
73
+ * Returns value ready to be encoded as JSON.
74
+ *
75
+ * The ISO-8601 range format is used for times.
76
+ *
67
77
* {@inheritdoc}
68
78
*/
69
- public function getBegin (): DateTimeInterface
79
+ public function jsonSerialize (): array
70
80
{
71
- return $ this ->begin ;
81
+ return $ this ->state -> jsonSerialize () ;
72
82
}
73
83
74
84
/**
75
85
* {@inheritdoc}
76
86
*/
77
- public function getEnd (): DateTimeInterface
87
+ public function hasStartTime (): bool
78
88
{
79
- return $ this ->end ;
89
+ return $ this ->state -> hasStartTime () ;
80
90
}
81
91
82
92
/**
83
93
* {@inheritdoc}
84
94
*/
85
- public function isFinite (): bool
95
+ public function hasEndTime (): bool
86
96
{
87
- return $ this ->end instanceof DateTimeInterface ;
97
+ return $ this ->state -> hasEndTime () ;
88
98
}
89
99
90
100
/**
91
101
* {@inheritdoc}
92
102
*/
93
- public function isBeginAt ( DateTimeInterface $ time ): bool
103
+ public function getStartTime ( ): DateTimeInterface
94
104
{
95
- return $ this ->begin -> getTimestamp () === $ time -> getTimestamp ();
105
+ return $ this ->state -> getStartTime ();
96
106
}
97
107
98
108
/**
99
109
* {@inheritdoc}
100
110
*/
101
- public function isEndAt ( DateTimeInterface $ time ): bool
111
+ public function getEndTime ( ): DateTimeInterface
102
112
{
103
- return $ this ->end -> getTimestamp () === $ time -> getTimestamp ();
113
+ return $ this ->state -> getEndTime ();
104
114
}
105
115
106
116
/**
107
117
* {@inheritdoc}
108
118
*/
109
- public function isStarted ( ): bool
119
+ public function setStartTime ( DateTimeInterface $ time ): DateRangeInterface
110
120
{
111
- return $ this -> begin <= new DateTimeImmutable () ;
112
- }
121
+ $ clone = clone $ this ;
122
+ $ clone -> state = $ clone -> state -> setStartTime ( $ time );
113
123
114
- /**
115
- * {@inheritdoc}
116
- */
117
- public function isEnded (): bool
118
- {
119
- return $ this ->isFinite () && $ this ->end <= new DateTimeImmutable ();
124
+ return $ clone ;
120
125
}
121
126
122
127
/**
123
128
* {@inheritdoc}
124
129
*/
125
- public function beginAt (DateTimeInterface $ time ): DateRangeInterface
130
+ public function setEndTime (DateTimeInterface $ time ): DateRangeInterface
126
131
{
127
- $ this ->guardDateSequence ($ time , $ this ->end );
132
+ $ clone = clone $ this ;
133
+ $ clone ->state = $ clone ->state ->setEndTime ($ time );
128
134
129
- $ this ->begin = $ time ;
130
-
131
- return $ this ;
135
+ return $ clone ;
132
136
}
133
137
134
138
/**
135
139
* {@inheritdoc}
136
140
*/
137
- public function endAt (DateTimeInterface $ time ): DateRangeInterface
141
+ public function isStartAt (DateTimeInterface $ time ): bool
138
142
{
139
- $ this ->guardDateSequence ($ this ->begin , $ time );
140
-
141
- $ this ->end = $ time ;
142
-
143
- return $ this ;
143
+ return $ this ->state ->isStartAt ($ time );
144
144
}
145
145
146
146
/**
147
147
* {@inheritdoc}
148
148
*/
149
- public function serialize ()
149
+ public function isEndAt ( DateTimeInterface $ time ): bool
150
150
{
151
- return sprintf (
152
- '%s/%s ' ,
153
- $ this ->getBegin ()->format ('c ' ),
154
- $ this ->isFinite ()
155
- ? $ this ->getEnd ()->format ('c ' )
156
- : '- '
157
- );
151
+ return $ this ->state ->isEndAt ($ time );
158
152
}
159
153
160
154
/**
161
155
* {@inheritdoc}
162
156
*/
163
- public function unserialize ( $ serialized )
157
+ public function isStarted (): bool
164
158
{
165
- $ times = explode ('/ ' , $ serialized , 2 );
166
-
167
- if (count ($ times ) !== 2 ) {
168
- throw new DateRangeException ('Invalid range format ' );
169
- }
170
-
171
- $ this ->begin = new DateTimeImmutable ($ times [0 ]);
172
-
173
- if ($ times [1 ] !== '- ' ) {
174
- $ this ->end = new DateTimeImmutable ($ times [1 ]);
175
- }
159
+ return $ this ->state ->isStarted ();
176
160
}
177
161
178
162
/**
179
163
* {@inheritdoc}
180
164
*/
181
- public function jsonSerialize ()
182
- {
183
- return $ this ->serialize ();
184
- }
185
-
186
- /**
187
- * @param DateTimeInterface $begin
188
- * @param DateTimeInterface|null $end
189
- */
190
- private function guardDateSequence (DateTimeInterface $ begin , DateTimeInterface $ end = null )
165
+ public function isEnded (): bool
191
166
{
192
- if ($ end && $ end <= $ begin ) {
193
- throw new DateRangeException ('Invalid end, must be after begin ' );
194
- }
167
+ return $ this ->state ->isEnded ();
195
168
}
196
169
}
0 commit comments