DateRange::__construct()   B
last analyzed

Complexity

Conditions 6
Paths 8

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 6

Importance

Changes 0
Metric Value
dl 0
loc 11
ccs 7
cts 7
cp 1
rs 8.8571
c 0
b 0
f 0
cc 6
eloc 6
nc 8
nop 2
crap 6
1
<?php
2
3
declare(strict_types = 1);
4
5
namespace Arbor\Moment;
6
7
use Arbor\Moment\Comparator\DateTimeComparator;
8
use Arbor\Moment\Exception\InvalidArgumentException;
9
use Arbor\Moment\Formatter\DateRangeFormatter;
10
11
/**
12
 * Class DateRange
13
 *
14
 * @package Arbor\Moment
15
 * @author Igor Vuckovic <[email protected]>
16
 */
17
class DateRange
18
{
19
    /** @var DateTime */
20
    private $startDate;
21
22
    /** @var DateTime */
23
    private $endDate;
24
25
    /** @var DateRangeFormatter */
26
    private $formatter;
27
28
    /**
29
     * @param DateTime|null $startDate
30
     * @param DateTime|null $endDate
31
     * @throws \InvalidArgumentException
32
     */
33 18
    public function __construct(DateTime $startDate = null, DateTime $endDate = null)
34
    {
35 18
        $this->startDate = $startDate ? clone $startDate : null;
36 18
        $this->endDate = $endDate ? clone $endDate : null;
37
38 18
        if ($startDate && $endDate && $endDate < $startDate) {
39 1
            throw InvalidArgumentException::startDateNotBeforeEndDate($startDate, $endDate);
40
        }
41
42 17
        $this->formatter = new DateRangeFormatter($this);
43 17
    }
44
45
    /**
46
     * @return DateTime|null
47
     */
48 26
    public function getStartDate()
49
    {
50 26
        return $this->startDate;
51
    }
52
53
    /**
54
     * @return DateTime|null
55
     */
56 22
    public function getEndDate()
57
    {
58 22
        return $this->endDate;
59
    }
60
61
    /**
62
     * @param DateTime $date
63
     * @return bool
64
     */
65 8
    public function containsDate(DateTime $date) : bool
66
    {
67 8
        if ($this->startDate === null) {
68 3
            return $this->endDate === null || $this->endDate >= $date;
69 5
        } elseif ($this->endDate === null) {
70 2
            return $this->startDate <= $date;
71
        }
72
73 3
        return $this->startDate <= $date && $this->endDate >= $date;
74
    }
75
76
    /**
77
     * @param DateRange $dateRange
78
     * @return bool
79
     */
80 10
    public function containsDateRange(DateRange $dateRange) : bool
81
    {
82 10
        if ($this->startDate === null && $this->endDate === null) {
83 4
            return true;
84
        }
85
86 6
        return $this->startDate <= $dateRange->getStartDate()
87 6
            && $dateRange->getEndDate() !== null
88 6
            && $this->endDate >= $dateRange->getEndDate();
89
    }
90
91
    /**
92
     * @param DateRange $dateRange
93
     * @return bool
94
     */
95 6
    public function overlapsDateRange(DateRange $dateRange) : bool
96
    {
97 6
        return $this->intersect($dateRange) !== null;
98
    }
99
100
    /**
101
     * @param DateTime $date
102
     * @return bool
103
     */
104 5
    public function isBefore(DateTime $date) : bool
105
    {
106 5
        if ($this->endDate === null) {
107 1
            return false;
108
        }
109
110 4
        return $this->endDate <= $date;
111
    }
112
113
    /**
114
     * @return bool
115
     */
116 1
    public function isNow() : bool
117
    {
118 1
        return $this->containsDate(new DateTime());
119
    }
120
121
    /**
122
     * @param DateTime $date
123
     * @return bool
124
     */
125 5
    public function isAfter(DateTime $date) : bool
126
    {
127 5
        if ($this->startDate === null) {
128 1
            return false;
129
        }
130
131 4
        return $this->startDate >= $date;
132
    }
133
134
    /**
135
     * @param DateRange $dateRange
136
     * @return DateRange|null
137
     */
138 9
    public function intersect(DateRange $dateRange)
139
    {
140 9
        $latestStartDate = DateTimeComparator::getLatestDate($this->startDate, $dateRange->startDate);
141 9
        $earliestEndDate = DateTimeComparator::getEarliestDate($this->endDate, $dateRange->endDate);
142
143 9
        if ($latestStartDate && $earliestEndDate && ($latestStartDate >= $earliestEndDate)) {
144 2
            return null;
145
        }
146
147 7
        return new DateRange($latestStartDate, $earliestEndDate);
148
    }
149
150
    /**
151
     * @param string $nullPlaceholder
152
     * @return string
153
     */
154 10
    public function getShort(string $nullPlaceholder = 'Ongoing') : string
155
    {
156 10
        return $this->formatter->getShort($nullPlaceholder);
157
    }
158
159
    /**
160
     * @param string $nullPlaceholder
161
     * @return string
162
     */
163 21
    public function getLong(string $nullPlaceholder = 'Ongoing') : string
164
    {
165 21
        return $this->formatter->getLong($nullPlaceholder);
166
    }
167
168
    /**
169
     * @return DateTime[]
170
     * @throws InvalidArgumentException
171
     */
172 4
    public function getAllDates() : array
173
    {
174 4
        if ($this->getStartDate() === null || $this->getEndDate() === null) {
175 3
            throw InvalidArgumentException::dateRangeWithoutBoundaries();
176
        }
177
178 1
        $startDate = $this->startDate;
179 1
        $endDate = $this->endDate;
180 1
        $referenceDate = clone $startDate;
181 1
        $referenceDate->setDateType(DateTime::TYPE_DATE);
182
183 1
        $dates = [];
184 1
        while ($referenceDate <= $endDate) {
185 1
            $dates[$referenceDate->getUnixTimestamp()] = clone $referenceDate;
186 1
            $referenceDate->add(new \DateInterval('P1D'));
187
        }
188
189 1
        return array_values($dates);
190
    }
191
192
    /**
193
     * @return Time|null
194
     */
195 4
    public function getDuration()
196
    {
197 4
        if ($this->startDate && $this->endDate) {
198 1
            return Time::fromSeconds($this->endDate->getTimestamp() - $this->startDate->getTimestamp());
199
        }
200
201 3
        return null;
202
    }
203
204
    /**
205
     * @return string
206
     */
207 7
    public function __toString() : string
208
    {
209 7
        return $this->getLong();
210
    }
211
212
    /**
213
     *
214
     */
215 1
    public function __clone()
216
    {
217 1
        $this->startDate = ($this->startDate ? clone $this->startDate : null);
218 1
        $this->endDate = ($this->endDate ? clone $this->endDate : null);
219 1
    }
220
}
221