DateRange::getEndDate()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
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 DateInterval;
14
use DatePeriod;
15
use DateTimeImmutable;
16
use DateTimeInterface;
17
use JsonSerializable;
18
use Traversable;
19
use Zee\DateRange\States\RangeState;
20
use Zee\DateRange\States\UndefinedState;
21
22
/**
23
 * Implementation of date range value object.
24
 */
25
final class DateRange implements DateRangeInterface, JsonSerializable
26
{
27
    /**
28
     * @var RangeState
29
     */
30
    private $state;
31
32
    /**
33
     * @param DateTimeInterface|null $startDate
34
     * @param DateTimeInterface|null $endDate
35
     */
36 10
    public function __construct(DateTimeInterface $startDate = null, DateTimeInterface $endDate = null)
37
    {
38 10
        $state = new UndefinedState();
39
40 10
        if (isset($startDate)) {
41 9
            $state = $state->setStartDate($startDate);
42
        }
43
44 10
        if (isset($endDate)) {
45 10
            $state = $state->setEndDate($endDate);
46
        }
47
48 10
        $this->state = $state;
49
    }
50
51
    /**
52
     * Returns string representation of range.
53
     *
54
     * {@inheritdoc}
55
     */
56 1
    public function __toString(): string
57
    {
58 1
        return sprintf(
59 1
            '%s/%s',
60 1
            $this->state->formatStartDate('c') ?: '-',
61 1
            $this->state->formatEndDate('c') ?: '-'
62
        );
63
    }
64
65
    /**
66
     * {@inheritdoc}
67
     */
68 1
    public function __debugInfo()
69
    {
70
        return [
71 1
            'startDate' => $this->state->hasStartDate()
72 1
                ? $this->state->getStartDate()
73
                : null,
74 1
            'endDate' => $this->state->hasEndDate()
75 1
                ? $this->state->getEndDate()
76
                : null,
77
        ];
78
    }
79
80
    /**
81
     * Returns value ready to be encoded as JSON.
82
     *
83
     * The ISO-8601 range format is used for times.
84
     *
85
     * {@inheritdoc}
86
     */
87 1
    public function jsonSerialize(): array
88
    {
89
        return [
90 1
            'startDate' => $this->state->formatStartDate(),
91 1
            'endDate' => $this->state->formatEndDate(),
92
        ];
93
    }
94
95
    /**
96
     * {@inheritdoc}
97
     */
98 2
    public function hasStartDate(): bool
99
    {
100 2
        return $this->state->hasStartDate();
101
    }
102
103
    /**
104
     * {@inheritdoc}
105
     */
106 2
    public function hasEndDate(): bool
107
    {
108 2
        return $this->state->hasEndDate();
109
    }
110
111
    /**
112
     * {@inheritdoc}
113
     */
114 6
    public function getStartDate(): DateTimeInterface
115
    {
116 6
        return $this->state->getStartDate();
117
    }
118
119
    /**
120
     * {@inheritdoc}
121
     */
122 6
    public function getEndDate(): DateTimeInterface
123
    {
124 6
        return $this->state->getEndDate();
125
    }
126
127
    /**
128
     * {@inheritdoc}
129
     */
130 1
    public function setStartDate(DateTimeInterface $start): DateRangeInterface
131
    {
132 1
        $clone = clone $this;
133 1
        $clone->state = $clone->state->setStartDate($start);
134
135 1
        return $clone;
136
    }
137
138
    /**
139
     * {@inheritdoc}
140
     */
141 1
    public function setEndDate(DateTimeInterface $end): DateRangeInterface
142
    {
143 1
        $clone = clone $this;
144 1
        $clone->state = $clone->state->setEndDate($end);
145
146 1
        return $clone;
147
    }
148
149
    /**
150
     * {@inheritdoc}
151
     */
152 1
    public function isFinite(): bool
153
    {
154 1
        return $this->hasStartDate() && $this->hasEndDate();
155
    }
156
157
    /**
158
     * {@inheritdoc}
159
     */
160 1
    public function isStartedOn(DateTimeInterface $date): bool
161
    {
162 1
        return $this->hasStartDate() && $this->state->compareStartDate($date) === 0;
163
    }
164
165
    /**
166
     * {@inheritdoc}
167
     */
168 1
    public function isEndedOn(DateTimeInterface $date): bool
169
    {
170 1
        return $this->hasEndDate() && $this->state->compareEndDate($date) === 0;
171
    }
172
173
    /**
174
     * {@inheritdoc}
175
     */
176 2
    public function isStarted(): bool
177
    {
178 2
        if ($this->hasStartDate()) {
179 1
            return $this->state->compareStartDate(new DateTimeImmutable()) <= 0;
180
        } else {
181 1
            return !$this->isEnded();
182
        }
183
    }
184
185
    /**
186
     * {@inheritdoc}
187
     */
188 2
    public function isEnded(): bool
189
    {
190 2
        return $this->hasEndDate() && $this->state->compareEndDate(new DateTimeImmutable()) < 0;
191
    }
192
193
    /**
194
     * {@inheritdoc}
195
     */
196 1
    public function getTimestampInterval(): int
197
    {
198 1
        return $this->getEndDate()->getTimestamp() - $this->getStartDate()->getTimestamp();
199
    }
200
201
    /**
202
     * {@inheritdoc}
203
     */
204 2
    public function getDateInterval(): DateInterval
205
    {
206 2
        return $this->getStartDate()->diff($this->getEndDate());
207
    }
208
209
    /**
210
     * {@inheritdoc}
211
     */
212 2
    public function getDatePeriod(DateInterval $interval, int $option = 0): DatePeriod
213
    {
214 2
        return new DatePeriod($this->getStartDate(), $interval, $this->getEndDate(), $option);
215
    }
216
217
    /**
218
     * {@inheritdoc}
219
     */
220 1
    public function split(DateInterval $interval): Traversable
221
    {
222 1
        $startDate = $this->getStartDate();
223 1
        $endDate = $this->getEndDate();
224 1
        $period = $this->getDatePeriod($interval, DatePeriod::EXCLUDE_START_DATE);
225
226 1
        foreach ($period as $date) {
227 1
            yield new DateRange($startDate, $date);
228 1
            $startDate = $date;
229
        }
230
231 1
        yield new DateRange($startDate, $endDate);
232
    }
233
}
234