Completed
Push — master ( 263e06...610eff )
by ignace nyamagana
14:40
created

functions.php ➔ day()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 3
dl 0
loc 12
rs 9.8666
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * League.Period (https://period.thephpleague.com).
5
 *
6
 * @author  Ignace Nyamagana Butera <[email protected]>
7
 * @license https://github.com/thephpleague/period/blob/master/LICENSE (MIT License)
8
 * @version 4.0.0
9
 * @link    https://github.com/thephpleague/period
10
 *
11
 * For the full copyright and license information, please view the LICENSE
12
 * file that was distributed with this source code.
13
 */
14
15
declare(strict_types=1);
16
17
namespace League\Period;
18
19
use DateInterval;
20
use DatePeriod;
21
use DateTime;
22
use DateTimeImmutable;
23
use DateTimeInterface;
24
use TypeError;
25
use const FILTER_VALIDATE_INT;
26
use function filter_var;
27
use function get_class;
28
use function gettype;
29
use function intdiv;
30
use function is_int;
31
use function is_object;
32
use function is_string;
33
use function sprintf;
34
35
/**
36
 * Returns a DateTimeImmutable object.
37
 *
38
 * @param int... $indexes
0 ignored issues
show
Documentation introduced by
The doc-type int... could not be parsed: Unknown type name "int..." at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
39
 */
40
function datepoint($datepoint, int ...$indexes): DateTimeImmutable
41
{
42
    if ($datepoint instanceof DateTimeImmutable) {
43
        return $datepoint;
44
    }
45
46
    if ($datepoint instanceof DateTime) {
47
        return DateTimeImmutable::createFromMutable($datepoint);
48
    }
49
50
    if (is_int($datepoint) && [] !== $indexes) {
51
        $indexes = $indexes + [1, 1, 0, 0, 0, 0];
52
53
        return (new DateTimeImmutable())
54
            ->setTime($indexes[2], $indexes[3], $indexes[4], $indexes[5])
55
            ->setDate($datepoint, $indexes[0], $indexes[1])
56
        ;
57
    }
58
59
    if (false !== ($res = filter_var($datepoint, FILTER_VALIDATE_INT))) {
60
        return new DateTimeImmutable('@'.$res);
61
    }
62
63
    if (is_string($datepoint)) {
64
        return new DateTimeImmutable($datepoint);
65
    }
66
67
    throw new TypeError(sprintf(
0 ignored issues
show
Unused Code introduced by
The call to TypeError::__construct() has too many arguments starting with \sprintf('The datepoint ...: \gettype($datepoint)).

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
68
        'The datepoint must be expressed using an integer, a string or a DateTimeInterface object %s given',
69
        is_object($datepoint) ? get_class($datepoint) : gettype($datepoint)
70
    ));
71
}
72
73
/**
74
 * Returns a DateInval object.
75
 *
76
 * The duration can be
77
 * <ul>
78
 * <li>a DateInterval object</li>
79
 * <li>an Interval object</li>
80
 * <li>an int interpreted as the duration expressed in seconds.</li>
81
 * <li>a string in a format supported by DateInterval::createFromDateString</li>
82
 * </ul>
83
 */
84
function duration($duration): DateInterval
85
{
86
    if ($duration instanceof Period) {
87
        return $duration->getDateInterval();
88
    }
89
90
    if ($duration instanceof DateInterval) {
91
        return $duration;
92
    }
93
94
    if (false !== ($res = filter_var($duration, FILTER_VALIDATE_INT))) {
95
        return new DateInterval('PT'.$res.'S');
96
    }
97
98
    if (is_string($duration)) {
99
        return DateInterval::createFromDateString($duration);
100
    }
101
102
    throw new TypeError(sprintf(
0 ignored issues
show
Unused Code introduced by
The call to TypeError::__construct() has too many arguments starting with \sprintf('The duration m... : \gettype($duration)).

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
103
        'The duration must be expressed using an integer, a string, a DateInterval or a Period object %s given',
104
        is_object($duration) ? get_class($duration) : gettype($duration)
105
    ));
106
}
107
108
/**
109
 * Creates new instance from a starting point and an interval.
110
 */
111
function interval_after($datepoint, $duration): Period
112
{
113
    $datepoint = datepoint($datepoint);
114
115
    return new Period($datepoint, $datepoint->add(duration($duration)));
116
}
117
118
/**
119
 * Creates new instance from a ending excluded datepoint and an interval.
120
 */
121
function interval_before($datepoint, $duration): Period
122
{
123
    $datepoint = datepoint($datepoint);
124
125
    return new Period($datepoint->sub(duration($duration)), $datepoint);
126
}
127
128
/**
129
 * Creates new instance where the given duration is simultaneously
130
 * substracted from and added to the datepoint.
131
 */
132
function interval_around($datepoint, $duration): Period
133
{
134
    $datepoint = datepoint($datepoint);
135
    $duration = duration($duration);
136
137
    return new Period($datepoint->sub($duration), $datepoint->add($duration));
138
}
139
140
/**
141
 * Creates new instance from a DatePeriod.
142
 *
143
 * @throws Exception If the submitted DatePeriod lacks an end datepoint.
144
 *                   This is possible if the DatePeriod was created using
145
 *                   recurrences instead of a end datepoint.
146
 *                   https://secure.php.net/manual/en/dateperiod.getenddate.php
147
 */
148
function interval_from_dateperiod(DatePeriod $datePeriod): Period
149
{
150
    $endDate = $datePeriod->getEndDate();
151
    if ($endDate instanceof DateTimeInterface) {
152
        return new Period($datePeriod->getStartDate(), $endDate);
153
    }
154
155
    throw new Exception('The submitted DatePeriod object does not contain an end datepoint');
156
}
157
158
/**
159
 * Creates new instance for a specific year.
160
 *
161
 * @param mixed $int_or_datepoint a year as an int or a datepoint
162
 */
163
function year($int_or_datepoint): Period
164
{
165
    if (!is_int($int_or_datepoint)) {
166
        $datepoint = datepoint($int_or_datepoint);
167
        $startDate = $datepoint->setTime(0, 0)->setDate((int) $datepoint->format('Y'), 1, 1);
168
169
        return new Period($startDate, $startDate->add(new DateInterval('P1Y')));
170
    }
171
172
    $startDate = datepoint($int_or_datepoint, 1, 1);
173
174
    return new Period($startDate, $startDate->add(new DateInterval('P1Y')));
175
}
176
177
/**
178
 * Creates new instance for a specific ISO year.
179
 *
180
 * @param mixed $int_or_datepoint a year as an int or a datepoint
181
 */
182
function iso_year($int_or_datepoint): Period
183
{
184
    if (!is_int($int_or_datepoint)) {
185
        $datepoint = datepoint($int_or_datepoint)->setTime(0, 0);
186
        $int_or_datepoint = (int) $datepoint->format('o');
187
188
        return new Period(
189
            $datepoint->setISODate($int_or_datepoint, 1),
190
            $datepoint->setISODate(++$int_or_datepoint, 1)
191
        );
192
    }
193
194
    $datepoint = datepoint($int_or_datepoint, 1, 1);
195
196
    return new Period(
197
        $datepoint->setISODate($int_or_datepoint, 1),
198
        $datepoint->setISODate(++$int_or_datepoint, 1)
199
    );
200
}
201
202
/**
203
 * Creates new instance for a specific semester in a given year.
204
 *
205
 * @param mixed $int_or_datepoint a year as an int or a datepoint
206
 * @param int   $index            a semester index from 1 to 2 included
207
 *
208
 * @throws Exception If the semester index is out of bounds
209
 */
210
function semester($int_or_datepoint, int $index = 1): Period
211
{
212
    if (!is_int($int_or_datepoint)) {
213
        $datepoint = datepoint($int_or_datepoint);
214
        $startDate = $datepoint->setTime(0, 0)->setDate(
215
            (int) $datepoint->format('Y'),
216
            (intdiv((int) $datepoint->format('n'), 6) * 6) + 1,
217
            1
218
        );
219
220
        return new Period($startDate, $startDate->add(new DateInterval('P6M')));
221
    }
222
223
    if (0 < $index && 2 >= $index) {
224
        $startDate = datepoint($int_or_datepoint, (($index - 1) * 6) + 1, 1);
225
226
        return new Period($startDate, $startDate->add(new DateInterval('P6M')));
227
    }
228
229
    throw new Exception(sprintf('The semester `%s` is not contained within the valid range.', $index));
230
}
231
232
/**
233
 * Creates new instance for a specific quarter in a given year.
234
 *
235
 * @param mixed $int_or_datepoint a year as an int or a datepoint
236
 * @param int   $index            quarter index from 1 to 4 included
237
 *
238
 * @throws Exception If the quarter index is out of bounds
239
 */
240
function quarter($int_or_datepoint, int $index = 1): Period
241
{
242
    if (!is_int($int_or_datepoint)) {
243
        $datepoint = datepoint($int_or_datepoint);
244
        $startDate = $datepoint->setTime(0, 0)->setDate(
245
            (int) $datepoint->format('Y'),
246
            (intdiv((int) $datepoint->format('n'), 3) * 3) + 1,
247
            1
248
        );
249
250
        return new Period($startDate, $startDate->add(new DateInterval('P3M')));
251
    }
252
253
    if (0 < $index && 4 >= $index) {
254
        $startDate = datepoint($int_or_datepoint, (($index - 1) * 3) + 1, 1);
255
256
        return new Period($startDate, $startDate->add(new DateInterval('P3M')));
257
    }
258
259
    throw new Exception(sprintf('The quarter `%s` is not contained within the valid range.', $index));
260
}
261
262
/**
263
 * Creates new instance for a specific year and month.
264
 *
265
 * @param mixed $int_or_datepoint a year as an int or a datepoint
266
 * @param int   $index            month index from 1 to 12 included
267
 *
268
 * @throws Exception If the month index is out of bounds
269
 */
270
function month($int_or_datepoint, int $index = 1): Period
271
{
272
    if (!is_int($int_or_datepoint)) {
273
        $datepoint = datepoint($int_or_datepoint);
274
        $startDate = $datepoint->setTime(0, 0)->setDate((int) $datepoint->format('Y'), (int) $datepoint->format('n'), 1);
275
276
        return new Period($startDate, $startDate->add(new DateInterval('P1M')));
277
    }
278
279
    $startDate = datepoint($int_or_datepoint, $index, 1);
280
281
    return new Period($startDate, $startDate->add(new DateInterval('P1M')));
282
}
283
284
/**
285
 * Creates new instance for a specific ISO8601 week.
286
 *
287
 * @param mixed $int_or_datepoint a year as an int or a datepoint
288
 * @param int   $index            index from 1 to 53 included
289
 *
290
 * @throws Exception If the week index for a given year is out of bounds
291
 */
292
function iso_week($int_or_datepoint, int $index = 1): Period
293
{
294
    if (!is_int($int_or_datepoint)) {
295
        $datepoint = datepoint($int_or_datepoint)->setTime(0, 0);
296
        $startDate = $datepoint->setISODate((int) $datepoint->format('o'), (int) $datepoint->format('W'), 1);
297
298
        return new Period($startDate, $startDate->add(new DateInterval('P7D')));
299
    }
300
301
    $datepoint = (new DateTimeImmutable())->setTime(0, 0)->setDate($int_or_datepoint, 12, 28);
302
    if (0 < $index && (int) $datepoint->format('W') >= $index) {
303
        $startDate = $datepoint->setISODate($int_or_datepoint, $index, 1);
304
305
        return new Period($startDate, $startDate->add(new DateInterval('P7D')));
306
    }
307
308
    throw new Exception('The week index is not contained within the valid range.');
309
}
310
311
/**
312
 * Creates new instance for a specific date.
313
 *
314
 * The date is truncated so that the time range starts at midnight
315
 * according to the date timezone and last a full day.
316
 *
317
 * @param mixed $int_or_datepoint a year as an int or a datepoint
318
 */
319
function day($int_or_datepoint, int $month = 1, int $day = 1): Period
320
{
321
    if (!is_int($int_or_datepoint)) {
322
        $startDate = datepoint($int_or_datepoint)->setTime(0, 0);
323
324
        return new Period($startDate, $startDate->add(new DateInterval('P1D')));
325
    }
326
327
    $startDate = datepoint($int_or_datepoint, $month, $day);
328
329
    return new Period($startDate, $startDate->add(new DateInterval('P1D')));
330
}
331
332
/**
333
 * Creates new instance for a specific date and hour.
334
 *
335
 * The starting datepoint represents the beginning of the hour
336
 * The interval is equal to 1 hour
337
 */
338
function hour($int_or_datepoint, int $month = 1, int $day = 1, int $hour = 0): Period
339
{
340
    if (!is_int($int_or_datepoint)) {
341
        $datepoint = datepoint($int_or_datepoint);
342
        $startDate = $datepoint->setTime((int) $datepoint->format('H'), 0);
343
344
        return new Period($startDate, $startDate->add(new DateInterval('PT1H')));
345
    }
346
347
    $startDate = datepoint($int_or_datepoint, $month, $day, $hour);
348
349
    return new Period($startDate, $startDate->add(new DateInterval('PT1H')));
350
}
351
352
/**
353
 * Creates new instance for a specific date, hour and minute.
354
 *
355
 * The starting datepoint represents the beginning of the minute
356
 * The interval is equal to 1 minute
357
 */
358
function minute($int_or_datepoint, int $month = 1, int $day = 1, int $hour = 0, int $minute = 0): Period
359
{
360
    if (!is_int($int_or_datepoint)) {
361
        $datepoint = datepoint($int_or_datepoint);
362
        $startDate = $datepoint->setTime((int) $datepoint->format('H'), (int) $datepoint->format('i'));
363
364
        return new Period($startDate, $startDate->add(new DateInterval('PT1M')));
365
    }
366
367
    $startDate = datepoint($int_or_datepoint, $month, $day, $hour, $minute);
368
369
    return new Period($startDate, $startDate->add(new DateInterval('PT1M')));
370
}
371
372
/**
373
 * Creates new instance for a specific date, hour, minute and second.
374
 *
375
 * The starting datepoint represents the beginning of the second
376
 * The interval is equal to 1 second
377
 */
378
function second($int_or_datepoint, int $month = 1, int $day = 1, int $hour = 0, int $minute = 0, int $second = 0): Period
379
{
380
    if (!is_int($int_or_datepoint)) {
381
        $datepoint = datepoint($int_or_datepoint);
382
        $startDate = $datepoint->setTime(
383
            (int) $datepoint->format('H'),
384
            (int) $datepoint->format('i'),
385
            (int) $datepoint->format('s')
386
        );
387
388
        return new Period($startDate, $startDate->add(new DateInterval('PT1S')));
389
    }
390
391
    $startDate = datepoint($int_or_datepoint, $month, $day, $hour, $minute, $second);
392
393
    return new Period($startDate, $startDate->add(new DateInterval('PT1S')));
394
}
395
396
/**
397
 * Creates new instance for a specific datepoint.
398
 */
399
function instant($datepoint): Period
400
{
401
    $datepoint = datepoint($datepoint);
402
403
    return new Period($datepoint, $datepoint);
404
}
405