MonthImmutable::equals()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 2
nc 2
nop 1
dl 0
loc 5
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Gearbox\DateTime;
4
5
/**
6
 * Represents a specific month of a year, e.g. July 2016
7
 */
8
class MonthImmutable
9
{
10
    /** @var integer */
11
    private $month;
12
13
    /** @var integer */
14
    private $year;
15
16
17
18
    /**
19
     * @param string $monthString Optional description of the month in the format 'YYYY-MM'.
20
     * @throws Exception
21
     */
22
    public function __construct($monthString = null)
23
    {
24
        // If constructed without parameters it represents todays month
25
        if (is_null($monthString)) {
26
            $monthString = date('Y-m');
27
        }
28
29
        try {
30
            // Split string at '-' into $year and $month
31
            if (strpos($monthString, '-') === false) {
32
                throw new Exception('The month string does not contain a hyphen.');
33
            } else {
34
                list($year, $month) = explode('-', $monthString);
35
            }
36
37
            // Make sure that strings have correct length and contain only digits
38
            if (strlen($year) == 4 && ctype_digit($year)) {
39
                $this->year = (int) $year;
40
            } else {
41
                throw new Exception('The year must be a four digit number.');
42
            }
43
44
            if (strlen($month) == 2 && ctype_digit($month)) {
45
                $this->month = (int) $month;
46
            } else {
47
                throw new Exception('The month must be a two digit number.');
48
            }
49
50
        } catch (Exception $exception) {
51
            throw new Exception('Cannot construct instance of'.__CLASS__.' with parameter "'.$monthString.'". Reason: ' . $exception->getMessage());
52
        }
53
    }
54
55
56
57
    /**
58
     * @param MonthImmutable $monthToCompareWith
59
     * @return boolean
60
     */
61
    public function isSameYear(MonthImmutable $monthToCompareWith)
62
    {
63
        $isSameYear = $this->getYearAsNumber() == $monthToCompareWith->getYearAsNumber();
64
65
        return $isSameYear;
66
    }
67
68
69
70
    /**
71
     * @param MonthImmutable $monthToCompareWith
72
     * @return boolean
73
     */
74
    public function isLaterYear(MonthImmutable $monthToCompareWith)
75
    {
76
        $isLaterYear = $this->getYearAsNumber() > $monthToCompareWith->getYearAsNumber();
77
78
        return $isLaterYear;
79
    }
80
81
82
83
    /**
84
     * @param MonthImmutable $monthToCompareWith
85
     * @return boolean
86
     */
87
    public function isSameMonthInTheYear(MonthImmutable $monthToCompareWith)
88
    {
89
        $isSameMonthInYear = $this->getMonthAsNumber() == $monthToCompareWith->getMonthAsNumber();
90
91
        return $isSameMonthInYear;
92
    }
93
94
95
96
    /**
97
     * @param MonthImmutable $monthToCompareWith
98
     * @return boolean
99
     */
100
    public function isLaterMonthInTheYear(MonthImmutable $monthToCompareWith)
101
    {
102
        $isLaterMonthInYear = $this->getMonthAsNumber() > $monthToCompareWith->getMonthAsNumber();
103
104
        return $isLaterMonthInYear;
105
    }
106
107
108
109
    /**
110
     * @param MonthImmutable $monthToCompareWith
111
     * @return boolean
112
     */
113
    public function isLaterMonthInSameYear(MonthImmutable $monthToCompareWith)
114
    {
115
        $isLaterMonthInSameYear = $this->isSameYear($monthToCompareWith) && $this->isLaterMonthInTheYear($monthToCompareWith);
116
117
        return $isLaterMonthInSameYear;
118
    }
119
120
121
122
    /**
123
     * Returns true if the given month represents the same month as this one.
124
     * 
125
     * @param MonthImmutable $monthToCompareWith
126
     * @return boolean
127
     */
128
    public function equals(MonthImmutable $monthToCompareWith)
129
    {
130
        $isEqual = $this->isSameMonthInTheYear($monthToCompareWith) && $this->isSameYear($monthToCompareWith);
131
132
        return $isEqual;
133
    }
134
135
136
137
    /**
138
     * @param MonthImmutable $monthToCompareWith
139
     * @return boolean
140
     */
141
    public function isLater(MonthImmutable $monthToCompareWith)
142
    {
143
        $isLater = $this->isLaterMonthInSameYear($monthToCompareWith) || $this->isLaterYear($monthToCompareWith);
144
145
        return $isLater;
146
    }
147
148
149
150
    /**
151
     * @return integer Month as number
152
     */
153
    public function getMonthAsNumber()
154
    {
155
        return $this->month;
156
    }
157
158
159
160
    /**
161
     * @return integer Year as four digit number
162
     */
163
    public function getYearAsNumber()
164
    {
165
        return $this->year;
166
    }
167
168
169
170
    /**
171
     * @return DateTimeImmutable
172
     */
173
    public function getBegin()
174
    {
175
        $start = new DateTimeImmutable($this->getYearMonthString().'-01 00:00:00');
176
177
        return $start;
178
    }
179
180
181
182
    /**
183
     * @return DateTimeImmutable
184
     */
185
    public function getEnd()
186
    {
187
        $end = $this->getBegin()->addMonths(1)->addDays(-1)->setTime(23, 59, 59);
188
189
        return $end;
190
    }
191
192
193
194
    /**
195
     * @return DateTimeImmutable
196
     */
197
    public function getFirstDay()
198
    {
199
        $firstDayOfMonth = new DateTimeImmutable($this->getYearMonthString().'-01 00:00:00');
200
201
        return $firstDayOfMonth;
202
    }
203
204
205
206
    public function getNextMonth()
207
    {
208
        $nextMonth = $this->addMonths(1);
209
210
        return $nextMonth;
211
    }
212
213
214
215
    public function getPreviousMonth()
216
    {
217
        $nextMonth = $this->subMonths(1);
218
219
        return $nextMonth;
220
    }
221
222
223
224
    public function addMonths(int $months): MonthImmutable
225
    {
226
        return $this->getBegin()->addMonths($months)->getMonth();
227
    }
228
229
230
231
    public function subMonths($diffInMonths)
232
    {
233
        $newMonth = $this->addMonths(-$diffInMonths);
234
235
        return $newMonth;
236
    }
237
238
239
240
    /**
241
     * @return string E.g. "2016-08"
242
     */
243
    public function getYearMonthString()
244
    {
245
        $yearMonthString = $this->buildYearMonthString($this->year, $this->month);
246
247
        return $yearMonthString;
248
    }
249
250
251
252
    public function __toString()
253
    {
254
        return $this->getFirstDay()->format('M Y');
255
    }
256
257
258
259
    private function buildYearMonthString($year, $month)
260
    {
261
        $yearMonthString = $year.'-'.str_pad($month, 2, '0', STR_PAD_LEFT);
262
263
        return $yearMonthString;
264
    }
265
}
266