Code Duplication    Length = 380-380 lines in 5 locations

src/Date/DateInterval.php 1 location

@@ 19-398 (lines=380) @@
16
use GpsLab\Component\Interval\IntervalPointInterface;
17
use GpsLab\Component\Interval\IntervalType;
18
19
class DateInterval implements ComparableIntervalInterface
20
{
21
    /**
22
     * @var string
23
     */
24
    const REGEXP = '/^
25
        (?:\(|\[)                   # start type char
26
        \s*
27
        (?<start>\d{4}-\d{2}-\d{2}) # start point
28
        \s*,\s*                     # separator
29
        (?<end>\d{4}-\d{2}-\d{2})   # end point
30
        \s*
31
        (?:\)|\])                   # end type char
32
    $/x';
33
34
    /**
35
     * @var IntervalType
36
     */
37
    private $type;
38
39
    /**
40
     * @var IntervalComparator
41
     */
42
    private $comparator;
43
44
    /**
45
     * @var DateIntervalPoint
46
     */
47
    private $start;
48
49
    /**
50
     * @var DateIntervalPoint
51
     */
52
    private $end;
53
54
    /**
55
     * @param DateIntervalPoint $start
56
     * @param DateIntervalPoint $end
57
     * @param IntervalType $type
58
     */
59
    private function __construct(DateIntervalPoint $start, DateIntervalPoint $end, IntervalType $type)
60
    {
61
        if ($start->gte($end)) {
62
            throw IncorrectIntervalException::create();
63
        }
64
65
        $this->type = $type;
66
        $this->start = $start;
67
        $this->end = $end;
68
        $this->comparator = new IntervalComparator($this);
69
    }
70
71
    /**
72
     * @param \DateTime $start
73
     * @param \DateTime $end
74
     * @param IntervalType $type
75
     *
76
     * @return self
77
     */
78
    public static function create(\DateTime $start, \DateTime $end, IntervalType $type)
79
    {
80
        return new self(new DateIntervalPoint($start), new DateIntervalPoint($end), $type);
81
    }
82
83
    /**
84
     * @param \DateTime $start
85
     * @param \DateTime $end
86
     *
87
     * @return self
88
     */
89
    public static function closed(\DateTime $start, \DateTime $end)
90
    {
91
        return static::create($start, $end, IntervalType::closed());
92
    }
93
94
    /**
95
     * @param \DateTime $start
96
     * @param \DateTime $end
97
     *
98
     * @return self
99
     */
100
    public static function halfClosed(\DateTime $start, \DateTime $end)
101
    {
102
        return static::create($start, $end, IntervalType::halfClosed());
103
    }
104
105
    /**
106
     * @param \DateTime $start
107
     * @param \DateTime $end
108
     *
109
     * @return self
110
     */
111
    public static function halfOpen(\DateTime $start, \DateTime $end)
112
    {
113
        return static::create($start, $end, IntervalType::halfOpen());
114
    }
115
116
    /**
117
     * @param \DateTime $start
118
     * @param \DateTime $end
119
     *
120
     * @return self
121
     */
122
    public static function open(\DateTime $start, \DateTime $end)
123
    {
124
        return static::create($start, $end, IntervalType::open());
125
    }
126
127
    /**
128
     * Create interval from string.
129
     *
130
     * Example formats for all interval types:
131
     *   [2016-12-09, 2016-12-21]
132
     *   (2015-03-07, 2015-10-19]
133
     *   [2014-09-11, 2015-02-08)
134
     *   (2013-10-27, 2013-10-30)
135
     *
136
     * Spaces are ignored in format.
137
     *
138
     * @param string $string
139
     *
140
     * @return self
141
     */
142
    public static function fromString($string)
143
    {
144
        if (!preg_match(self::REGEXP, $string, $match)) {
145
            throw InvalidIntervalFormatException::create('[YYYY-MM-DD, YYYY-MM-DD]', $string);
146
        }
147
148
        return self::create(
149
            new \DateTime($match['start']),
150
            new \DateTime($match['end']),
151
            IntervalType::fromString($string)
152
        );
153
    }
154
155
    /**
156
     * Checks if this interval is equal to the specified interval.
157
     *
158
     * @param DateInterval $interval
159
     *
160
     * @return bool
161
     */
162
    public function equal(DateInterval $interval)
163
    {
164
        return $this->comparator->equal($interval);
165
    }
166
167
    /**
168
     * Does this interval contain the specified point.
169
     *
170
     * @param \DateTime $point
171
     *
172
     * @return bool
173
     */
174
    public function contains(\DateTime $point)
175
    {
176
        return $this->comparator->contains(new DateIntervalPoint($point));
177
    }
178
179
    /**
180
     * Does this interval intersect the specified interval.
181
     *
182
     * @param DateInterval $interval
183
     *
184
     * @return bool
185
     */
186
    public function intersects(DateInterval $interval)
187
    {
188
        return $this->comparator->intersects($interval);
189
    }
190
191
    /**
192
     * Gets the intersection between this interval and another interval.
193
     *
194
     * @param DateInterval $interval
195
     *
196
     * @return self|null
197
     */
198
    public function intersection(DateInterval $interval)
199
    {
200
        return $this->comparator->intersection($interval);
201
    }
202
203
    /**
204
     * Gets the covered interval between this Interval and another interval.
205
     *
206
     * @param DateInterval $interval
207
     *
208
     * @return self
209
     */
210
    public function cover(DateInterval $interval)
211
    {
212
        return $this->comparator->cover($interval);
213
    }
214
215
    /**
216
     * Gets the gap between this interval and another interval.
217
     *
218
     * @param DateInterval $interval
219
     *
220
     * @return self|null
221
     */
222
    public function gap(DateInterval $interval)
223
    {
224
        return $this->comparator->gap($interval);
225
    }
226
227
    /**
228
     * Does this interval abut with the interval specified.
229
     *
230
     * @param DateInterval $interval
231
     *
232
     * @return bool
233
     */
234
    public function abuts(DateInterval $interval)
235
    {
236
        return $this->comparator->abuts($interval);
237
    }
238
239
    /**
240
     * Joins the interval between the adjacent.
241
     *
242
     * @param DateInterval $interval
243
     *
244
     * @return self|null
245
     */
246
    public function join(DateInterval $interval)
247
    {
248
        return $this->comparator->join($interval);
249
    }
250
251
    /**
252
     * Gets the union between this interval and another interval.
253
     *
254
     * @param DateInterval $interval
255
     *
256
     * @return self|null
257
     */
258
    public function union(DateInterval $interval)
259
    {
260
        return $this->comparator->union($interval);
261
    }
262
263
    /**
264
     * The point is before the interval.
265
     *
266
     * @param \DateTime $point
267
     *
268
     * @return bool
269
     */
270
    public function before(\DateTime $point)
271
    {
272
        return $this->comparator->before(new DateIntervalPoint($point));
273
    }
274
275
    /**
276
     * The point is after the interval.
277
     *
278
     * @param \DateTime $point
279
     *
280
     * @return bool
281
     */
282
    public function after(\DateTime $point)
283
    {
284
        return $this->comparator->after(new DateIntervalPoint($point));
285
    }
286
287
    /**
288
     * @param \DateInterval|null $step
289
     *
290
     * @return \Generator
291
     */
292
    public function iterate(\DateInterval $step = null)
293
    {
294
        $step = $step ?: new \DateInterval('P1D');
295
296
        $date = $this->start();
297
        while ($date < $this->end()) {
298
            yield $date;
299
            $date->add($step);
300
        }
301
    }
302
303
    /**
304
     * @param \DateInterval|null $step
305
     *
306
     * @return \DatePeriod
307
     */
308
    public function period(\DateInterval $step = null)
309
    {
310
        $step = $step ?: new \DateInterval('P1D');
311
312
        return new \DatePeriod($this->start(), $step, $this->end());
313
    }
314
315
    /**
316
     * @return IntervalType
317
     */
318
    public function type()
319
    {
320
        return $this->type;
321
    }
322
323
    /**
324
     * @return \DateTime
325
     */
326
    public function start()
327
    {
328
        return $this->start->value();
329
    }
330
331
    /**
332
     * @return \DateTime
333
     */
334
    public function end()
335
    {
336
        return $this->end->value();
337
    }
338
339
    /**
340
     * @return DateIntervalPoint
341
     */
342
    public function startPoint()
343
    {
344
        return $this->start;
345
    }
346
347
    /**
348
     * @return DateIntervalPoint
349
     */
350
    public function endPoint()
351
    {
352
        return $this->end;
353
    }
354
355
    /**
356
     * Returns a copy of this Interval with the start point altered.
357
     *
358
     * @param IntervalPointInterface|DateIntervalPoint $start
359
     *
360
     * @return self
361
     */
362
    public function withStart(IntervalPointInterface $start)
363
    {
364
        return new self($start, $this->end, $this->type);
365
    }
366
367
    /**
368
     * Returns a copy of this Interval with the end point altered.
369
     *
370
     * @param IntervalPointInterface|DateIntervalPoint $end
371
     *
372
     * @return self
373
     */
374
    public function withEnd(IntervalPointInterface $end)
375
    {
376
        return new self($this->start, $end, $this->type);
377
    }
378
379
    /**
380
     * Returns a copy of this Interval with the interval type altered.
381
     *
382
     * @param IntervalType $type
383
     *
384
     * @return self
385
     */
386
    public function withType(IntervalType $type)
387
    {
388
        return new self($this->start, $this->end, $type);
389
    }
390
391
    /**
392
     * @return string
393
     */
394
    public function __toString()
395
    {
396
        return $this->type->getReadable($this);
397
    }
398
}
399

src/DateTime/DateTimeInterval.php 1 location

@@ 19-398 (lines=380) @@
16
use GpsLab\Component\Interval\IntervalPointInterface;
17
use GpsLab\Component\Interval\IntervalType;
18
19
class DateTimeInterval implements ComparableIntervalInterface
20
{
21
    /**
22
     * @var string
23
     */
24
    const REGEXP = '/^
25
        (?:\(|\[)                                       # start type char
26
        \s*
27
        (?<start>\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2}) # start point
28
        \s*,\s*                                         # separator
29
        (?<end>\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2})   # end point
30
        \s*
31
        (?:\)|\])                                       # end type char
32
    $/x';
33
34
    /**
35
     * @var IntervalType
36
     */
37
    private $type;
38
39
    /**
40
     * @var IntervalComparator
41
     */
42
    private $comparator;
43
44
    /**
45
     * @var DateTimeIntervalPoint
46
     */
47
    private $start;
48
49
    /**
50
     * @var DateTimeIntervalPoint
51
     */
52
    private $end;
53
54
    /**
55
     * @param DateTimeIntervalPoint $start
56
     * @param DateTimeIntervalPoint $end
57
     * @param IntervalType $type
58
     */
59
    private function __construct(DateTimeIntervalPoint $start, DateTimeIntervalPoint $end, IntervalType $type)
60
    {
61
        if ($start->gte($end)) {
62
            throw IncorrectIntervalException::create();
63
        }
64
65
        $this->type = $type;
66
        $this->start = $start;
67
        $this->end = $end;
68
        $this->comparator = new IntervalComparator($this);
69
    }
70
71
    /**
72
     * @param \DateTime $start
73
     * @param \DateTime $end
74
     * @param IntervalType $type
75
     *
76
     * @return self
77
     */
78
    public static function create(\DateTime $start, \DateTime $end, IntervalType $type)
79
    {
80
        return new self(new DateTimeIntervalPoint($start), new DateTimeIntervalPoint($end), $type);
81
    }
82
83
    /**
84
     * @param \DateTime $start
85
     * @param \DateTime $end
86
     *
87
     * @return self
88
     */
89
    public static function closed(\DateTime $start, \DateTime $end)
90
    {
91
        return static::create($start, $end, IntervalType::closed());
92
    }
93
94
    /**
95
     * @param \DateTime $start
96
     * @param \DateTime $end
97
     *
98
     * @return self
99
     */
100
    public static function halfClosed(\DateTime $start, \DateTime $end)
101
    {
102
        return static::create($start, $end, IntervalType::halfClosed());
103
    }
104
105
    /**
106
     * @param \DateTime $start
107
     * @param \DateTime $end
108
     *
109
     * @return self
110
     */
111
    public static function halfOpen(\DateTime $start, \DateTime $end)
112
    {
113
        return static::create($start, $end, IntervalType::halfOpen());
114
    }
115
116
    /**
117
     * @param \DateTime $start
118
     * @param \DateTime $end
119
     *
120
     * @return self
121
     */
122
    public static function open(\DateTime $start, \DateTime $end)
123
    {
124
        return static::create($start, $end, IntervalType::open());
125
    }
126
127
    /**
128
     * Create interval from string.
129
     *
130
     * Example formats for all interval types:
131
     *   [2016-12-09 02:55:00, 2016-12-21 12:30:12]
132
     *   (2015-03-07 12:04:45, 2015-10-19 19:38:14]
133
     *   [2014-09-11 17:31:09, 2015-02-08 23:45:58)
134
     *   (2013-10-27 15:03:37, 2013-10-30 05:06:34)
135
     *
136
     * Spaces are ignored in format.
137
     *
138
     * @param string $string
139
     *
140
     * @return self
141
     */
142
    public static function fromString($string)
143
    {
144
        if (!preg_match(self::REGEXP, $string, $match)) {
145
            throw InvalidIntervalFormatException::create('[YYYY-MM-DD HH:II:SS, YYYY-MM-DD HH:II:SS]', $string);
146
        }
147
148
        return self::create(
149
            new \DateTime($match['start']),
150
            new \DateTime($match['end']),
151
            IntervalType::fromString($string)
152
        );
153
    }
154
155
    /**
156
     * Checks if this interval is equal to the specified interval.
157
     *
158
     * @param DateTimeInterval $interval
159
     *
160
     * @return bool
161
     */
162
    public function equal(DateTimeInterval $interval)
163
    {
164
        return $this->comparator->equal($interval);
165
    }
166
167
    /**
168
     * Does this interval contain the specified point.
169
     *
170
     * @param \DateTime $point
171
     *
172
     * @return bool
173
     */
174
    public function contains(\DateTime $point)
175
    {
176
        return $this->comparator->contains(new DateTimeIntervalPoint($point));
177
    }
178
179
    /**
180
     * Does this interval intersect the specified interval.
181
     *
182
     * @param DateTimeInterval $interval
183
     *
184
     * @return bool
185
     */
186
    public function intersects(DateTimeInterval $interval)
187
    {
188
        return $this->comparator->intersects($interval);
189
    }
190
191
    /**
192
     * Gets the intersection between this interval and another interval.
193
     *
194
     * @param DateTimeInterval $interval
195
     *
196
     * @return self|null
197
     */
198
    public function intersection(DateTimeInterval $interval)
199
    {
200
        return $this->comparator->intersection($interval);
201
    }
202
203
    /**
204
     * Gets the covered interval between this Interval and another interval.
205
     *
206
     * @param DateTimeInterval $interval
207
     *
208
     * @return self
209
     */
210
    public function cover(DateTimeInterval $interval)
211
    {
212
        return $this->comparator->cover($interval);
213
    }
214
215
    /**
216
     * Gets the gap between this interval and another interval.
217
     *
218
     * @param DateTimeInterval $interval
219
     *
220
     * @return self|null
221
     */
222
    public function gap(DateTimeInterval $interval)
223
    {
224
        return $this->comparator->gap($interval);
225
    }
226
227
    /**
228
     * Does this interval abut with the interval specified.
229
     *
230
     * @param DateTimeInterval $interval
231
     *
232
     * @return bool
233
     */
234
    public function abuts(DateTimeInterval $interval)
235
    {
236
        return $this->comparator->abuts($interval);
237
    }
238
239
    /**
240
     * Joins the interval between the adjacent.
241
     *
242
     * @param DateTimeInterval $interval
243
     *
244
     * @return self|null
245
     */
246
    public function join(DateTimeInterval $interval)
247
    {
248
        return $this->comparator->join($interval);
249
    }
250
251
    /**
252
     * Gets the union between this interval and another interval.
253
     *
254
     * @param DateTimeInterval $interval
255
     *
256
     * @return self|null
257
     */
258
    public function union(DateTimeInterval $interval)
259
    {
260
        return $this->comparator->union($interval);
261
    }
262
263
    /**
264
     * The point is before the interval.
265
     *
266
     * @param \DateTime $point
267
     *
268
     * @return bool
269
     */
270
    public function before(\DateTime $point)
271
    {
272
        return $this->comparator->before(new DateTimeIntervalPoint($point));
273
    }
274
275
    /**
276
     * The point is after the interval.
277
     *
278
     * @param \DateTime $point
279
     *
280
     * @return bool
281
     */
282
    public function after(\DateTime $point)
283
    {
284
        return $this->comparator->after(new DateTimeIntervalPoint($point));
285
    }
286
287
    /**
288
     * @param \DateInterval|null $step
289
     *
290
     * @return \Generator
291
     */
292
    public function iterate(\DateInterval $step = null)
293
    {
294
        $step = $step ?: new \DateInterval('P1D');
295
296
        $date = $this->start();
297
        while ($date < $this->end()) {
298
            yield $date;
299
            $date->add($step);
300
        }
301
    }
302
303
    /**
304
     * @param \DateInterval|null $step
305
     *
306
     * @return \DatePeriod
307
     */
308
    public function period(\DateInterval $step = null)
309
    {
310
        $step = $step ?: new \DateInterval('P1D');
311
312
        return new \DatePeriod($this->start(), $step, $this->end());
313
    }
314
315
    /**
316
     * @return IntervalType
317
     */
318
    public function type()
319
    {
320
        return $this->type;
321
    }
322
323
    /**
324
     * @return \DateTime
325
     */
326
    public function start()
327
    {
328
        return $this->start->value();
329
    }
330
331
    /**
332
     * @return \DateTime
333
     */
334
    public function end()
335
    {
336
        return $this->end->value();
337
    }
338
339
    /**
340
     * @return DateTimeIntervalPoint
341
     */
342
    public function startPoint()
343
    {
344
        return $this->start;
345
    }
346
347
    /**
348
     * @return DateTimeIntervalPoint
349
     */
350
    public function endPoint()
351
    {
352
        return $this->end;
353
    }
354
355
    /**
356
     * Returns a copy of this Interval with the start point altered.
357
     *
358
     * @param IntervalPointInterface|DateTimeIntervalPoint $start
359
     *
360
     * @return self
361
     */
362
    public function withStart(IntervalPointInterface $start)
363
    {
364
        return new self($start, $this->end, $this->type);
365
    }
366
367
    /**
368
     * Returns a copy of this Interval with the end point altered.
369
     *
370
     * @param IntervalPointInterface|DateTimeIntervalPoint $end
371
     *
372
     * @return self
373
     */
374
    public function withEnd(IntervalPointInterface $end)
375
    {
376
        return new self($this->start, $end, $this->type);
377
    }
378
379
    /**
380
     * Returns a copy of this Interval with the interval type altered.
381
     *
382
     * @param IntervalType $type
383
     *
384
     * @return self
385
     */
386
    public function withType(IntervalType $type)
387
    {
388
        return new self($this->start, $this->end, $type);
389
    }
390
391
    /**
392
     * @return string
393
     */
394
    public function __toString()
395
    {
396
        return $this->type->getReadable($this);
397
    }
398
}
399

src/Month/MonthInterval.php 1 location

@@ 20-399 (lines=380) @@
17
use GpsLab\Component\Interval\IntervalPointInterface;
18
use GpsLab\Component\Interval\IntervalType;
19
20
class MonthInterval implements ComparableIntervalInterface
21
{
22
    /**
23
     * @var string
24
     */
25
    const REGEXP = '/^
26
        (?:\(|\[)              # start type char
27
        \s*
28
        (?<start>\d{4}\/\d{2}) # start point
29
        \s*,\s*                # separator
30
        (?<end>\d{4}\/\d{2})   # end point
31
        \s*
32
        (?:\)|\])              # end type char
33
    $/x';
34
35
    /**
36
     * @var IntervalType
37
     */
38
    private $type;
39
40
    /**
41
     * @var IntervalComparator
42
     */
43
    private $comparator;
44
45
    /**
46
     * @var MonthIntervalPoint
47
     */
48
    private $start;
49
50
    /**
51
     * @var MonthIntervalPoint
52
     */
53
    private $end;
54
55
    /**
56
     * @param MonthIntervalPoint $start
57
     * @param MonthIntervalPoint $end
58
     * @param IntervalType $type
59
     */
60
    private function __construct(MonthIntervalPoint $start, MonthIntervalPoint $end, IntervalType $type)
61
    {
62
        if ($start->gte($end)) {
63
            throw IncorrectIntervalException::create();
64
        }
65
66
        $this->type = $type;
67
        $this->start = $start;
68
        $this->end = $end;
69
        $this->comparator = new IntervalComparator($this);
70
    }
71
72
    /**
73
     * @param \DateTime $start
74
     * @param \DateTime $end
75
     * @param IntervalType $type
76
     *
77
     * @return self
78
     */
79
    public static function create(\DateTime $start, \DateTime $end, IntervalType $type)
80
    {
81
        return new self(new MonthIntervalPoint($start), new MonthIntervalPoint($end), $type);
82
    }
83
84
    /**
85
     * @param \DateTime $start
86
     * @param \DateTime $end
87
     *
88
     * @return self
89
     */
90
    public static function closed(\DateTime $start, \DateTime $end)
91
    {
92
        return static::create($start, $end, IntervalType::closed());
93
    }
94
95
    /**
96
     * @param \DateTime $start
97
     * @param \DateTime $end
98
     *
99
     * @return self
100
     */
101
    public static function halfClosed(\DateTime $start, \DateTime $end)
102
    {
103
        return static::create($start, $end, IntervalType::halfClosed());
104
    }
105
106
    /**
107
     * @param \DateTime $start
108
     * @param \DateTime $end
109
     *
110
     * @return self
111
     */
112
    public static function halfOpen(\DateTime $start, \DateTime $end)
113
    {
114
        return static::create($start, $end, IntervalType::halfOpen());
115
    }
116
117
    /**
118
     * @param \DateTime $start
119
     * @param \DateTime $end
120
     *
121
     * @return self
122
     */
123
    public static function open(\DateTime $start, \DateTime $end)
124
    {
125
        return static::create($start, $end, IntervalType::open());
126
    }
127
128
    /**
129
     * Create interval from string.
130
     *
131
     * Example formats for all interval types:
132
     *   [2016/12, 2016/12]
133
     *   (2015/03, 2015/10]
134
     *   [2014/09, 2015/02)
135
     *   (2013/10, 2013/10)
136
     *
137
     * Spaces are ignored in format.
138
     *
139
     * @param string $string
140
     *
141
     * @return self
142
     */
143
    public static function fromString($string)
144
    {
145
        if (!preg_match(self::REGEXP, $string, $match)) {
146
            throw InvalidIntervalFormatException::create('[YYYY/MM, YYYY/MM]', $string);
147
        }
148
149
        return self::create(
150
            new \DateTime($match['start'].'/01'),
151
            new \DateTime($match['end'].'/01'),
152
            IntervalType::fromString($string)
153
        );
154
    }
155
156
    /**
157
     * Checks if this interval is equal to the specified interval.
158
     *
159
     * @param MonthInterval $interval
160
     *
161
     * @return bool
162
     */
163
    public function equal(MonthInterval $interval)
164
    {
165
        return $this->comparator->equal($interval);
166
    }
167
168
    /**
169
     * Does this interval contain the specified point.
170
     *
171
     * @param \DateTime $point
172
     *
173
     * @return bool
174
     */
175
    public function contains(\DateTime $point)
176
    {
177
        return $this->comparator->contains(new MonthIntervalPoint($point));
178
    }
179
180
    /**
181
     * Does this interval intersect the specified interval.
182
     *
183
     * @param MonthInterval $interval
184
     *
185
     * @return bool
186
     */
187
    public function intersects(MonthInterval $interval)
188
    {
189
        return $this->comparator->intersects($interval);
190
    }
191
192
    /**
193
     * Gets the intersection between this interval and another interval.
194
     *
195
     * @param MonthInterval $interval
196
     *
197
     * @return self|null
198
     */
199
    public function intersection(MonthInterval $interval)
200
    {
201
        return $this->comparator->intersection($interval);
202
    }
203
204
    /**
205
     * Gets the covered interval between this Interval and another interval.
206
     *
207
     * @param MonthInterval $interval
208
     *
209
     * @return self
210
     */
211
    public function cover(MonthInterval $interval)
212
    {
213
        return $this->comparator->cover($interval);
214
    }
215
216
    /**
217
     * Gets the gap between this interval and another interval.
218
     *
219
     * @param MonthInterval $interval
220
     *
221
     * @return self|null
222
     */
223
    public function gap(MonthInterval $interval)
224
    {
225
        return $this->comparator->gap($interval);
226
    }
227
228
    /**
229
     * Does this interval abut with the interval specified.
230
     *
231
     * @param MonthInterval $interval
232
     *
233
     * @return bool
234
     */
235
    public function abuts(MonthInterval $interval)
236
    {
237
        return $this->comparator->abuts($interval);
238
    }
239
240
    /**
241
     * Joins the interval between the adjacent.
242
     *
243
     * @param MonthInterval $interval
244
     *
245
     * @return self|null
246
     */
247
    public function join(MonthInterval $interval)
248
    {
249
        return $this->comparator->join($interval);
250
    }
251
252
    /**
253
     * Gets the union between this interval and another interval.
254
     *
255
     * @param MonthInterval $interval
256
     *
257
     * @return self|null
258
     */
259
    public function union(MonthInterval $interval)
260
    {
261
        return $this->comparator->union($interval);
262
    }
263
264
    /**
265
     * The point is before the interval.
266
     *
267
     * @param \DateTime $point
268
     *
269
     * @return bool
270
     */
271
    public function before(\DateTime $point)
272
    {
273
        return $this->comparator->before(new MonthIntervalPoint($point));
274
    }
275
276
    /**
277
     * The point is after the interval.
278
     *
279
     * @param \DateTime $point
280
     *
281
     * @return bool
282
     */
283
    public function after(\DateTime $point)
284
    {
285
        return $this->comparator->after(new MonthIntervalPoint($point));
286
    }
287
288
    /**
289
     * @param \DateInterval|null $step
290
     *
291
     * @return \Generator
292
     */
293
    public function iterate(\DateInterval $step = null)
294
    {
295
        $step = $step ?: new \DateInterval('P1M');
296
297
        $date = $this->start();
298
        while ($date < $this->end()) {
299
            yield $date;
300
            $date->add($step);
301
        }
302
    }
303
304
    /**
305
     * @param \DateInterval|null $step
306
     *
307
     * @return \DatePeriod
308
     */
309
    public function period(\DateInterval $step = null)
310
    {
311
        $step = $step ?: new \DateInterval('P1M');
312
313
        return new \DatePeriod($this->start(), $step, $this->end());
314
    }
315
316
    /**
317
     * @return IntervalType
318
     */
319
    public function type()
320
    {
321
        return $this->type;
322
    }
323
324
    /**
325
     * @return \DateTime
326
     */
327
    public function start()
328
    {
329
        return $this->start->value();
330
    }
331
332
    /**
333
     * @return \DateTime
334
     */
335
    public function end()
336
    {
337
        return $this->end->value();
338
    }
339
340
    /**
341
     * @return MonthIntervalPoint
342
     */
343
    public function startPoint()
344
    {
345
        return $this->start;
346
    }
347
348
    /**
349
     * @return MonthIntervalPoint
350
     */
351
    public function endPoint()
352
    {
353
        return $this->end;
354
    }
355
356
    /**
357
     * Returns a copy of this Interval with the start point altered.
358
     *
359
     * @param IntervalPointInterface|MonthIntervalPoint $start
360
     *
361
     * @return self
362
     */
363
    public function withStart(IntervalPointInterface $start)
364
    {
365
        return new self($start, $this->end, $this->type);
366
    }
367
368
    /**
369
     * Returns a copy of this Interval with the end point altered.
370
     *
371
     * @param IntervalPointInterface|MonthIntervalPoint $end
372
     *
373
     * @return self
374
     */
375
    public function withEnd(IntervalPointInterface $end)
376
    {
377
        return new self($this->start, $end, $this->type);
378
    }
379
380
    /**
381
     * Returns a copy of this Interval with the interval type altered.
382
     *
383
     * @param IntervalType $type
384
     *
385
     * @return self
386
     */
387
    public function withType(IntervalType $type)
388
    {
389
        return new self($this->start, $this->end, $type);
390
    }
391
392
    /**
393
     * @return string
394
     */
395
    public function __toString()
396
    {
397
        return $this->type->getReadable($this);
398
    }
399
}
400

src/Time/TimeInterval.php 1 location

@@ 20-399 (lines=380) @@
17
use GpsLab\Component\Interval\IntervalPointInterface;
18
use GpsLab\Component\Interval\IntervalType;
19
20
class TimeInterval implements ComparableIntervalInterface
21
{
22
    /**
23
     * @var string
24
     */
25
    const REGEXP = '/^
26
        (?:\(|\[)                   # start type char
27
        \s*
28
        (?<start>\d{2}:\d{2}:\d{2}) # start point
29
        \s*,\s*                     # separator
30
        (?<end>\d{2}:\d{2}:\d{2})   # end point
31
        \s*
32
        (?:\)|\])                   # end type char
33
    $/x';
34
35
    /**
36
     * @var IntervalType
37
     */
38
    private $type;
39
40
    /**
41
     * @var IntervalComparator
42
     */
43
    private $comparator;
44
45
    /**
46
     * @var TimeIntervalPoint
47
     */
48
    private $start;
49
50
    /**
51
     * @var TimeIntervalPoint
52
     */
53
    private $end;
54
55
    /**
56
     * @param TimeIntervalPoint $start
57
     * @param TimeIntervalPoint $end
58
     * @param IntervalType $type
59
     */
60
    private function __construct(TimeIntervalPoint $start, TimeIntervalPoint $end, IntervalType $type)
61
    {
62
        if ($start->gte($end)) {
63
            throw IncorrectIntervalException::create();
64
        }
65
66
        $this->type = $type;
67
        $this->start = $start;
68
        $this->end = $end;
69
        $this->comparator = new IntervalComparator($this);
70
    }
71
72
    /**
73
     * @param \DateTime $start
74
     * @param \DateTime $end
75
     * @param IntervalType $type
76
     *
77
     * @return self
78
     */
79
    public static function create(\DateTime $start, \DateTime $end, IntervalType $type)
80
    {
81
        return new self(new TimeIntervalPoint($start), new TimeIntervalPoint($end), $type);
82
    }
83
84
    /**
85
     * @param \DateTime $start
86
     * @param \DateTime $end
87
     *
88
     * @return self
89
     */
90
    public static function closed(\DateTime $start, \DateTime $end)
91
    {
92
        return static::create($start, $end, IntervalType::closed());
93
    }
94
95
    /**
96
     * @param \DateTime $start
97
     * @param \DateTime $end
98
     *
99
     * @return self
100
     */
101
    public static function halfClosed(\DateTime $start, \DateTime $end)
102
    {
103
        return static::create($start, $end, IntervalType::halfClosed());
104
    }
105
106
    /**
107
     * @param \DateTime $start
108
     * @param \DateTime $end
109
     *
110
     * @return self
111
     */
112
    public static function halfOpen(\DateTime $start, \DateTime $end)
113
    {
114
        return static::create($start, $end, IntervalType::halfOpen());
115
    }
116
117
    /**
118
     * @param \DateTime $start
119
     * @param \DateTime $end
120
     *
121
     * @return self
122
     */
123
    public static function open(\DateTime $start, \DateTime $end)
124
    {
125
        return static::create($start, $end, IntervalType::open());
126
    }
127
128
    /**
129
     * Create interval from string.
130
     *
131
     * Example formats for all interval types:
132
     *   [02:55:00, 12:30:12]
133
     *   (12:04:45, 19:38:14]
134
     *   [17:31:09, 23:45:58)
135
     *   (15:03:37, 15:06:34)
136
     *
137
     * Spaces are ignored in format.
138
     *
139
     * @param string $string
140
     *
141
     * @return self
142
     */
143
    public static function fromString($string)
144
    {
145
        if (!preg_match(self::REGEXP, $string, $match)) {
146
            throw InvalidIntervalFormatException::create('[HH:II:SS, HH:II:SS]', $string);
147
        }
148
149
        return self::create(
150
            new \DateTime($match['start']),
151
            new \DateTime($match['end']),
152
            IntervalType::fromString($string)
153
        );
154
    }
155
156
    /**
157
     * Checks if this interval is equal to the specified interval.
158
     *
159
     * @param TimeInterval $interval
160
     *
161
     * @return bool
162
     */
163
    public function equal(TimeInterval $interval)
164
    {
165
        return $this->comparator->equal($interval);
166
    }
167
168
    /**
169
     * Does this interval contain the specified point.
170
     *
171
     * @param \DateTime $point
172
     *
173
     * @return bool
174
     */
175
    public function contains(\DateTime $point)
176
    {
177
        return $this->comparator->contains(new TimeIntervalPoint($point));
178
    }
179
180
    /**
181
     * Does this interval intersect the specified interval.
182
     *
183
     * @param TimeInterval $interval
184
     *
185
     * @return bool
186
     */
187
    public function intersects(TimeInterval $interval)
188
    {
189
        return $this->comparator->intersects($interval);
190
    }
191
192
    /**
193
     * Gets the intersection between this interval and another interval.
194
     *
195
     * @param TimeInterval $interval
196
     *
197
     * @return self|null
198
     */
199
    public function intersection(TimeInterval $interval)
200
    {
201
        return $this->comparator->intersection($interval);
202
    }
203
204
    /**
205
     * Gets the covered interval between this Interval and another interval.
206
     *
207
     * @param TimeInterval $interval
208
     *
209
     * @return self
210
     */
211
    public function cover(TimeInterval $interval)
212
    {
213
        return $this->comparator->cover($interval);
214
    }
215
216
    /**
217
     * Gets the gap between this interval and another interval.
218
     *
219
     * @param TimeInterval $interval
220
     *
221
     * @return self|null
222
     */
223
    public function gap(TimeInterval $interval)
224
    {
225
        return $this->comparator->gap($interval);
226
    }
227
228
    /**
229
     * Does this interval abut with the interval specified.
230
     *
231
     * @param TimeInterval $interval
232
     *
233
     * @return bool
234
     */
235
    public function abuts(TimeInterval $interval)
236
    {
237
        return $this->comparator->abuts($interval);
238
    }
239
240
    /**
241
     * Joins the interval between the adjacent.
242
     *
243
     * @param TimeInterval $interval
244
     *
245
     * @return self|null
246
     */
247
    public function join(TimeInterval $interval)
248
    {
249
        return $this->comparator->join($interval);
250
    }
251
252
    /**
253
     * Gets the union between this interval and another interval.
254
     *
255
     * @param TimeInterval $interval
256
     *
257
     * @return self|null
258
     */
259
    public function union(TimeInterval $interval)
260
    {
261
        return $this->comparator->union($interval);
262
    }
263
264
    /**
265
     * The point is before the interval.
266
     *
267
     * @param \DateTime $point
268
     *
269
     * @return bool
270
     */
271
    public function before(\DateTime $point)
272
    {
273
        return $this->comparator->before(new TimeIntervalPoint($point));
274
    }
275
276
    /**
277
     * The point is after the interval.
278
     *
279
     * @param \DateTime $point
280
     *
281
     * @return bool
282
     */
283
    public function after(\DateTime $point)
284
    {
285
        return $this->comparator->after(new TimeIntervalPoint($point));
286
    }
287
288
    /**
289
     * @param \DateInterval|null $step
290
     *
291
     * @return \Generator
292
     */
293
    public function iterate(\DateInterval $step = null)
294
    {
295
        $step = $step ?: new \DateInterval('PT1M');
296
297
        $date = $this->start();
298
        while ($date < $this->end()) {
299
            yield $date;
300
            $date->add($step);
301
        }
302
    }
303
304
    /**
305
     * @param \DateInterval|null $step
306
     *
307
     * @return \DatePeriod
308
     */
309
    public function period(\DateInterval $step = null)
310
    {
311
        $step = $step ?: new \DateInterval('PT1M');
312
313
        return new \DatePeriod($this->start(), $step, $this->end());
314
    }
315
316
    /**
317
     * @return IntervalType
318
     */
319
    public function type()
320
    {
321
        return $this->type;
322
    }
323
324
    /**
325
     * @return \DateTime
326
     */
327
    public function start()
328
    {
329
        return $this->start->value();
330
    }
331
332
    /**
333
     * @return \DateTime
334
     */
335
    public function end()
336
    {
337
        return $this->end->value();
338
    }
339
340
    /**
341
     * @return TimeIntervalPoint
342
     */
343
    public function startPoint()
344
    {
345
        return $this->start;
346
    }
347
348
    /**
349
     * @return TimeIntervalPoint
350
     */
351
    public function endPoint()
352
    {
353
        return $this->end;
354
    }
355
356
    /**
357
     * Returns a copy of this Interval with the start point altered.
358
     *
359
     * @param IntervalPointInterface|TimeIntervalPoint $start
360
     *
361
     * @return self
362
     */
363
    public function withStart(IntervalPointInterface $start)
364
    {
365
        return new self($start, $this->end, $this->type);
366
    }
367
368
    /**
369
     * Returns a copy of this Interval with the end point altered.
370
     *
371
     * @param IntervalPointInterface|TimeIntervalPoint $end
372
     *
373
     * @return self
374
     */
375
    public function withEnd(IntervalPointInterface $end)
376
    {
377
        return new self($this->start, $end, $this->type);
378
    }
379
380
    /**
381
     * Returns a copy of this Interval with the interval type altered.
382
     *
383
     * @param IntervalType $type
384
     *
385
     * @return self
386
     */
387
    public function withType(IntervalType $type)
388
    {
389
        return new self($this->start, $this->end, $type);
390
    }
391
392
    /**
393
     * @return string
394
     */
395
    public function __toString()
396
    {
397
        return $this->type->getReadable($this);
398
    }
399
}
400

src/Week/WeekInterval.php 1 location

@@ 20-399 (lines=380) @@
17
use GpsLab\Component\Interval\IntervalPointInterface;
18
use GpsLab\Component\Interval\IntervalType;
19
20
class WeekInterval implements ComparableIntervalInterface
21
{
22
    /**
23
     * @var string
24
     */
25
    const REGEXP = '/^
26
        (?:\(|\[)                   # start type char
27
        \s*
28
        (?<start>\d{4}-\d{2}-\d{2}) # start point
29
        \s*,\s*                     # separator
30
        (?<end>\d{4}-\d{2}-\d{2})   # end point
31
        \s*
32
        (?:\)|\])                   # end type char
33
    $/x';
34
35
    /**
36
     * @var IntervalType
37
     */
38
    private $type;
39
40
    /**
41
     * @var IntervalComparator
42
     */
43
    private $comparator;
44
45
    /**
46
     * @var WeekIntervalPoint
47
     */
48
    private $start;
49
50
    /**
51
     * @var WeekIntervalPoint
52
     */
53
    private $end;
54
55
    /**
56
     * @param WeekIntervalPoint $start
57
     * @param WeekIntervalPoint $end
58
     * @param IntervalType $type
59
     */
60
    private function __construct(WeekIntervalPoint $start, WeekIntervalPoint $end, IntervalType $type)
61
    {
62
        if ($start->gte($end)) {
63
            throw IncorrectIntervalException::create();
64
        }
65
66
        $this->type = $type;
67
        $this->start = $start;
68
        $this->end = $end;
69
        $this->comparator = new IntervalComparator($this);
70
    }
71
72
    /**
73
     * @param \DateTime $start
74
     * @param \DateTime $end
75
     * @param IntervalType $type
76
     *
77
     * @return self
78
     */
79
    public static function create(\DateTime $start, \DateTime $end, IntervalType $type)
80
    {
81
        return new self(new WeekIntervalPoint($start), new WeekIntervalPoint($end), $type);
82
    }
83
84
    /**
85
     * @param \DateTime $start
86
     * @param \DateTime $end
87
     *
88
     * @return self
89
     */
90
    public static function closed(\DateTime $start, \DateTime $end)
91
    {
92
        return static::create($start, $end, IntervalType::closed());
93
    }
94
95
    /**
96
     * @param \DateTime $start
97
     * @param \DateTime $end
98
     *
99
     * @return self
100
     */
101
    public static function halfClosed(\DateTime $start, \DateTime $end)
102
    {
103
        return static::create($start, $end, IntervalType::halfClosed());
104
    }
105
106
    /**
107
     * @param \DateTime $start
108
     * @param \DateTime $end
109
     *
110
     * @return self
111
     */
112
    public static function halfOpen(\DateTime $start, \DateTime $end)
113
    {
114
        return static::create($start, $end, IntervalType::halfOpen());
115
    }
116
117
    /**
118
     * @param \DateTime $start
119
     * @param \DateTime $end
120
     *
121
     * @return self
122
     */
123
    public static function open(\DateTime $start, \DateTime $end)
124
    {
125
        return static::create($start, $end, IntervalType::open());
126
    }
127
128
    /**
129
     * Create interval from string.
130
     *
131
     * Example formats for all interval types:
132
     *   [2016-12-09, 2016-12-21]
133
     *   (2015-03-07, 2015-10-19]
134
     *   [2014-09-11, 2015-02-08)
135
     *   (2013-10-02, 2013-10-30)
136
     *
137
     * Spaces are ignored in format.
138
     *
139
     * @param string $string
140
     *
141
     * @return self
142
     */
143
    public static function fromString($string)
144
    {
145
        if (!preg_match(self::REGEXP, $string, $match)) {
146
            throw InvalidIntervalFormatException::create('[YYYY-MM-DD, YYYY-MM-DD]', $string);
147
        }
148
149
        return self::create(
150
            new \DateTime($match['start']),
151
            new \DateTime($match['end']),
152
            IntervalType::fromString($string)
153
        );
154
    }
155
156
    /**
157
     * Checks if this interval is equal to the specified interval.
158
     *
159
     * @param WeekInterval $interval
160
     *
161
     * @return bool
162
     */
163
    public function equal(WeekInterval $interval)
164
    {
165
        return $this->comparator->equal($interval);
166
    }
167
168
    /**
169
     * Does this interval contain the specified point.
170
     *
171
     * @param \DateTime $point
172
     *
173
     * @return bool
174
     */
175
    public function contains(\DateTime $point)
176
    {
177
        return $this->comparator->contains(new WeekIntervalPoint($point));
178
    }
179
180
    /**
181
     * Does this interval intersect the specified interval.
182
     *
183
     * @param WeekInterval $interval
184
     *
185
     * @return bool
186
     */
187
    public function intersects(WeekInterval $interval)
188
    {
189
        return $this->comparator->intersects($interval);
190
    }
191
192
    /**
193
     * Gets the intersection between this interval and another interval.
194
     *
195
     * @param WeekInterval $interval
196
     *
197
     * @return self|null
198
     */
199
    public function intersection(WeekInterval $interval)
200
    {
201
        return $this->comparator->intersection($interval);
202
    }
203
204
    /**
205
     * Gets the covered interval between this Interval and another interval.
206
     *
207
     * @param WeekInterval $interval
208
     *
209
     * @return self
210
     */
211
    public function cover(WeekInterval $interval)
212
    {
213
        return $this->comparator->cover($interval);
214
    }
215
216
    /**
217
     * Gets the gap between this interval and another interval.
218
     *
219
     * @param WeekInterval $interval
220
     *
221
     * @return self|null
222
     */
223
    public function gap(WeekInterval $interval)
224
    {
225
        return $this->comparator->gap($interval);
226
    }
227
228
    /**
229
     * Does this interval abut with the interval specified.
230
     *
231
     * @param WeekInterval $interval
232
     *
233
     * @return bool
234
     */
235
    public function abuts(WeekInterval $interval)
236
    {
237
        return $this->comparator->abuts($interval);
238
    }
239
240
    /**
241
     * Joins the interval between the adjacent.
242
     *
243
     * @param WeekInterval $interval
244
     *
245
     * @return self|null
246
     */
247
    public function join(WeekInterval $interval)
248
    {
249
        return $this->comparator->join($interval);
250
    }
251
252
    /**
253
     * Gets the union between this interval and another interval.
254
     *
255
     * @param WeekInterval $interval
256
     *
257
     * @return self|null
258
     */
259
    public function union(WeekInterval $interval)
260
    {
261
        return $this->comparator->union($interval);
262
    }
263
264
    /**
265
     * The point is before the interval.
266
     *
267
     * @param \DateTime $point
268
     *
269
     * @return bool
270
     */
271
    public function before(\DateTime $point)
272
    {
273
        return $this->comparator->before(new WeekIntervalPoint($point));
274
    }
275
276
    /**
277
     * The point is after the interval.
278
     *
279
     * @param \DateTime $point
280
     *
281
     * @return bool
282
     */
283
    public function after(\DateTime $point)
284
    {
285
        return $this->comparator->after(new WeekIntervalPoint($point));
286
    }
287
288
    /**
289
     * @param \DateInterval|null $step
290
     *
291
     * @return \Generator
292
     */
293
    public function iterate(\DateInterval $step = null)
294
    {
295
        $step = $step ?: new \DateInterval('P1W');
296
297
        $date = $this->start();
298
        while ($date < $this->end()) {
299
            yield $date;
300
            $date->add($step);
301
        }
302
    }
303
304
    /**
305
     * @param \DateInterval|null $step
306
     *
307
     * @return \DatePeriod
308
     */
309
    public function period(\DateInterval $step = null)
310
    {
311
        $step = $step ?: new \DateInterval('P1W');
312
313
        return new \DatePeriod($this->start(), $step, $this->end());
314
    }
315
316
    /**
317
     * @return IntervalType
318
     */
319
    public function type()
320
    {
321
        return $this->type;
322
    }
323
324
    /**
325
     * @return \DateTime
326
     */
327
    public function start()
328
    {
329
        return $this->start->value();
330
    }
331
332
    /**
333
     * @return \DateTime
334
     */
335
    public function end()
336
    {
337
        return $this->end->value();
338
    }
339
340
    /**
341
     * @return WeekIntervalPoint
342
     */
343
    public function startPoint()
344
    {
345
        return $this->start;
346
    }
347
348
    /**
349
     * @return WeekIntervalPoint
350
     */
351
    public function endPoint()
352
    {
353
        return $this->end;
354
    }
355
356
    /**
357
     * Returns a copy of this Interval with the start point altered.
358
     *
359
     * @param IntervalPointInterface|WeekIntervalPoint $start
360
     *
361
     * @return self
362
     */
363
    public function withStart(IntervalPointInterface $start)
364
    {
365
        return new self($start, $this->end, $this->type);
366
    }
367
368
    /**
369
     * Returns a copy of this Interval with the end point altered.
370
     *
371
     * @param IntervalPointInterface|WeekIntervalPoint $end
372
     *
373
     * @return self
374
     */
375
    public function withEnd(IntervalPointInterface $end)
376
    {
377
        return new self($this->start, $end, $this->type);
378
    }
379
380
    /**
381
     * Returns a copy of this Interval with the interval type altered.
382
     *
383
     * @param IntervalType $type
384
     *
385
     * @return self
386
     */
387
    public function withType(IntervalType $type)
388
    {
389
        return new self($this->start, $this->end, $type);
390
    }
391
392
    /**
393
     * @return string
394
     */
395
    public function __toString()
396
    {
397
        return $this->type->getReadable($this);
398
    }
399
}
400