Subversion-Projekte lars-tiefland.laravel_shop

Revision

Zur aktuellen Revision | Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
148 lars 1
<?php
2
 
3
/**
4
 * This file is part of the Carbon package.
5
 *
6
 * (c) Brian Nesbitt <brian@nesbot.com>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
 
12
namespace Carbon\Traits;
13
 
14
use BadMethodCallException;
15
use Carbon\CarbonInterface;
16
use Carbon\Exceptions\BadComparisonUnitException;
17
use InvalidArgumentException;
18
 
19
/**
20
 * Trait Comparison.
21
 *
22
 * Comparison utils and testers. All the following methods return booleans.
23
 * nowWithSameTz
24
 *
25
 * Depends on the following methods:
26
 *
27
 * @method static        resolveCarbon($date)
28
 * @method static        copy()
29
 * @method static        nowWithSameTz()
30
 * @method static static yesterday($timezone = null)
31
 * @method static static tomorrow($timezone = null)
32
 */
33
trait Comparison
34
{
35
    /** @var bool */
36
    protected $endOfTime = false;
37
 
38
    /** @var bool */
39
    protected $startOfTime = false;
40
 
41
    /**
42
     * Determines if the instance is equal to another
43
     *
44
     * @example
45
     * ```
46
     * Carbon::parse('2018-07-25 12:45:16')->eq('2018-07-25 12:45:16'); // true
47
     * Carbon::parse('2018-07-25 12:45:16')->eq(Carbon::parse('2018-07-25 12:45:16')); // true
48
     * Carbon::parse('2018-07-25 12:45:16')->eq('2018-07-25 12:45:17'); // false
49
     * ```
50
     *
51
     * @param \Carbon\Carbon|\DateTimeInterface|mixed $date
52
     *
53
     * @see equalTo()
54
     *
55
     * @return bool
56
     */
57
    public function eq($date): bool
58
    {
59
        return $this->equalTo($date);
60
    }
61
 
62
    /**
63
     * Determines if the instance is equal to another
64
     *
65
     * @example
66
     * ```
67
     * Carbon::parse('2018-07-25 12:45:16')->equalTo('2018-07-25 12:45:16'); // true
68
     * Carbon::parse('2018-07-25 12:45:16')->equalTo(Carbon::parse('2018-07-25 12:45:16')); // true
69
     * Carbon::parse('2018-07-25 12:45:16')->equalTo('2018-07-25 12:45:17'); // false
70
     * ```
71
     *
72
     * @param \Carbon\Carbon|\DateTimeInterface|mixed $date
73
     *
74
     * @return bool
75
     */
76
    public function equalTo($date): bool
77
    {
78
        $this->discourageNull($date);
79
        $this->discourageBoolean($date);
80
 
81
        return $this == $this->resolveCarbon($date);
82
    }
83
 
84
    /**
85
     * Determines if the instance is not equal to another
86
     *
87
     * @example
88
     * ```
89
     * Carbon::parse('2018-07-25 12:45:16')->ne('2018-07-25 12:45:16'); // false
90
     * Carbon::parse('2018-07-25 12:45:16')->ne(Carbon::parse('2018-07-25 12:45:16')); // false
91
     * Carbon::parse('2018-07-25 12:45:16')->ne('2018-07-25 12:45:17'); // true
92
     * ```
93
     *
94
     * @param \Carbon\Carbon|\DateTimeInterface|mixed $date
95
     *
96
     * @see notEqualTo()
97
     *
98
     * @return bool
99
     */
100
    public function ne($date): bool
101
    {
102
        return $this->notEqualTo($date);
103
    }
104
 
105
    /**
106
     * Determines if the instance is not equal to another
107
     *
108
     * @example
109
     * ```
110
     * Carbon::parse('2018-07-25 12:45:16')->notEqualTo('2018-07-25 12:45:16'); // false
111
     * Carbon::parse('2018-07-25 12:45:16')->notEqualTo(Carbon::parse('2018-07-25 12:45:16')); // false
112
     * Carbon::parse('2018-07-25 12:45:16')->notEqualTo('2018-07-25 12:45:17'); // true
113
     * ```
114
     *
115
     * @param \Carbon\Carbon|\DateTimeInterface|mixed $date
116
     *
117
     * @return bool
118
     */
119
    public function notEqualTo($date): bool
120
    {
121
        return !$this->equalTo($date);
122
    }
123
 
124
    /**
125
     * Determines if the instance is greater (after) than another
126
     *
127
     * @example
128
     * ```
129
     * Carbon::parse('2018-07-25 12:45:16')->gt('2018-07-25 12:45:15'); // true
130
     * Carbon::parse('2018-07-25 12:45:16')->gt('2018-07-25 12:45:16'); // false
131
     * Carbon::parse('2018-07-25 12:45:16')->gt('2018-07-25 12:45:17'); // false
132
     * ```
133
     *
134
     * @param \Carbon\Carbon|\DateTimeInterface|mixed $date
135
     *
136
     * @see greaterThan()
137
     *
138
     * @return bool
139
     */
140
    public function gt($date): bool
141
    {
142
        return $this->greaterThan($date);
143
    }
144
 
145
    /**
146
     * Determines if the instance is greater (after) than another
147
     *
148
     * @example
149
     * ```
150
     * Carbon::parse('2018-07-25 12:45:16')->greaterThan('2018-07-25 12:45:15'); // true
151
     * Carbon::parse('2018-07-25 12:45:16')->greaterThan('2018-07-25 12:45:16'); // false
152
     * Carbon::parse('2018-07-25 12:45:16')->greaterThan('2018-07-25 12:45:17'); // false
153
     * ```
154
     *
155
     * @param \Carbon\Carbon|\DateTimeInterface|mixed $date
156
     *
157
     * @return bool
158
     */
159
    public function greaterThan($date): bool
160
    {
161
        $this->discourageNull($date);
162
        $this->discourageBoolean($date);
163
 
164
        return $this > $this->resolveCarbon($date);
165
    }
166
 
167
    /**
168
     * Determines if the instance is greater (after) than another
169
     *
170
     * @example
171
     * ```
172
     * Carbon::parse('2018-07-25 12:45:16')->isAfter('2018-07-25 12:45:15'); // true
173
     * Carbon::parse('2018-07-25 12:45:16')->isAfter('2018-07-25 12:45:16'); // false
174
     * Carbon::parse('2018-07-25 12:45:16')->isAfter('2018-07-25 12:45:17'); // false
175
     * ```
176
     *
177
     * @param \Carbon\Carbon|\DateTimeInterface|mixed $date
178
     *
179
     * @see greaterThan()
180
     *
181
     * @return bool
182
     */
183
    public function isAfter($date): bool
184
    {
185
        return $this->greaterThan($date);
186
    }
187
 
188
    /**
189
     * Determines if the instance is greater (after) than or equal to another
190
     *
191
     * @example
192
     * ```
193
     * Carbon::parse('2018-07-25 12:45:16')->gte('2018-07-25 12:45:15'); // true
194
     * Carbon::parse('2018-07-25 12:45:16')->gte('2018-07-25 12:45:16'); // true
195
     * Carbon::parse('2018-07-25 12:45:16')->gte('2018-07-25 12:45:17'); // false
196
     * ```
197
     *
198
     * @param \Carbon\Carbon|\DateTimeInterface|mixed $date
199
     *
200
     * @see greaterThanOrEqualTo()
201
     *
202
     * @return bool
203
     */
204
    public function gte($date): bool
205
    {
206
        return $this->greaterThanOrEqualTo($date);
207
    }
208
 
209
    /**
210
     * Determines if the instance is greater (after) than or equal to another
211
     *
212
     * @example
213
     * ```
214
     * Carbon::parse('2018-07-25 12:45:16')->greaterThanOrEqualTo('2018-07-25 12:45:15'); // true
215
     * Carbon::parse('2018-07-25 12:45:16')->greaterThanOrEqualTo('2018-07-25 12:45:16'); // true
216
     * Carbon::parse('2018-07-25 12:45:16')->greaterThanOrEqualTo('2018-07-25 12:45:17'); // false
217
     * ```
218
     *
219
     * @param \Carbon\Carbon|\DateTimeInterface|mixed $date
220
     *
221
     * @return bool
222
     */
223
    public function greaterThanOrEqualTo($date): bool
224
    {
225
        $this->discourageNull($date);
226
        $this->discourageBoolean($date);
227
 
228
        return $this >= $this->resolveCarbon($date);
229
    }
230
 
231
    /**
232
     * Determines if the instance is less (before) than another
233
     *
234
     * @example
235
     * ```
236
     * Carbon::parse('2018-07-25 12:45:16')->lt('2018-07-25 12:45:15'); // false
237
     * Carbon::parse('2018-07-25 12:45:16')->lt('2018-07-25 12:45:16'); // false
238
     * Carbon::parse('2018-07-25 12:45:16')->lt('2018-07-25 12:45:17'); // true
239
     * ```
240
     *
241
     * @param \Carbon\Carbon|\DateTimeInterface|mixed $date
242
     *
243
     * @see lessThan()
244
     *
245
     * @return bool
246
     */
247
    public function lt($date): bool
248
    {
249
        return $this->lessThan($date);
250
    }
251
 
252
    /**
253
     * Determines if the instance is less (before) than another
254
     *
255
     * @example
256
     * ```
257
     * Carbon::parse('2018-07-25 12:45:16')->lessThan('2018-07-25 12:45:15'); // false
258
     * Carbon::parse('2018-07-25 12:45:16')->lessThan('2018-07-25 12:45:16'); // false
259
     * Carbon::parse('2018-07-25 12:45:16')->lessThan('2018-07-25 12:45:17'); // true
260
     * ```
261
     *
262
     * @param \Carbon\Carbon|\DateTimeInterface|mixed $date
263
     *
264
     * @return bool
265
     */
266
    public function lessThan($date): bool
267
    {
268
        $this->discourageNull($date);
269
        $this->discourageBoolean($date);
270
 
271
        return $this < $this->resolveCarbon($date);
272
    }
273
 
274
    /**
275
     * Determines if the instance is less (before) than another
276
     *
277
     * @example
278
     * ```
279
     * Carbon::parse('2018-07-25 12:45:16')->isBefore('2018-07-25 12:45:15'); // false
280
     * Carbon::parse('2018-07-25 12:45:16')->isBefore('2018-07-25 12:45:16'); // false
281
     * Carbon::parse('2018-07-25 12:45:16')->isBefore('2018-07-25 12:45:17'); // true
282
     * ```
283
     *
284
     * @param \Carbon\Carbon|\DateTimeInterface|mixed $date
285
     *
286
     * @see lessThan()
287
     *
288
     * @return bool
289
     */
290
    public function isBefore($date): bool
291
    {
292
        return $this->lessThan($date);
293
    }
294
 
295
    /**
296
     * Determines if the instance is less (before) or equal to another
297
     *
298
     * @example
299
     * ```
300
     * Carbon::parse('2018-07-25 12:45:16')->lte('2018-07-25 12:45:15'); // false
301
     * Carbon::parse('2018-07-25 12:45:16')->lte('2018-07-25 12:45:16'); // true
302
     * Carbon::parse('2018-07-25 12:45:16')->lte('2018-07-25 12:45:17'); // true
303
     * ```
304
     *
305
     * @param \Carbon\Carbon|\DateTimeInterface|mixed $date
306
     *
307
     * @see lessThanOrEqualTo()
308
     *
309
     * @return bool
310
     */
311
    public function lte($date): bool
312
    {
313
        return $this->lessThanOrEqualTo($date);
314
    }
315
 
316
    /**
317
     * Determines if the instance is less (before) or equal to another
318
     *
319
     * @example
320
     * ```
321
     * Carbon::parse('2018-07-25 12:45:16')->lessThanOrEqualTo('2018-07-25 12:45:15'); // false
322
     * Carbon::parse('2018-07-25 12:45:16')->lessThanOrEqualTo('2018-07-25 12:45:16'); // true
323
     * Carbon::parse('2018-07-25 12:45:16')->lessThanOrEqualTo('2018-07-25 12:45:17'); // true
324
     * ```
325
     *
326
     * @param \Carbon\Carbon|\DateTimeInterface|mixed $date
327
     *
328
     * @return bool
329
     */
330
    public function lessThanOrEqualTo($date): bool
331
    {
332
        $this->discourageNull($date);
333
        $this->discourageBoolean($date);
334
 
335
        return $this <= $this->resolveCarbon($date);
336
    }
337
 
338
    /**
339
     * Determines if the instance is between two others.
340
     *
341
     * The third argument allow you to specify if bounds are included or not (true by default)
342
     * but for when you including/excluding bounds may produce different results in your application,
343
     * we recommend to use the explicit methods ->betweenIncluded() or ->betweenExcluded() instead.
344
     *
345
     * @example
346
     * ```
347
     * Carbon::parse('2018-07-25')->between('2018-07-14', '2018-08-01'); // true
348
     * Carbon::parse('2018-07-25')->between('2018-08-01', '2018-08-20'); // false
349
     * Carbon::parse('2018-07-25')->between('2018-07-25', '2018-08-01'); // true
350
     * Carbon::parse('2018-07-25')->between('2018-07-25', '2018-08-01', false); // false
351
     * ```
352
     *
353
     * @param \Carbon\Carbon|\DateTimeInterface|mixed $date1
354
     * @param \Carbon\Carbon|\DateTimeInterface|mixed $date2
355
     * @param bool                                    $equal Indicates if an equal to comparison should be done
356
     *
357
     * @return bool
358
     */
359
    public function between($date1, $date2, $equal = true): bool
360
    {
361
        $date1 = $this->resolveCarbon($date1);
362
        $date2 = $this->resolveCarbon($date2);
363
 
364
        if ($date1->greaterThan($date2)) {
365
            [$date1, $date2] = [$date2, $date1];
366
        }
367
 
368
        if ($equal) {
369
            return $this >= $date1 && $this <= $date2;
370
        }
371
 
372
        return $this > $date1 && $this < $date2;
373
    }
374
 
375
    /**
376
     * Determines if the instance is between two others, bounds included.
377
     *
378
     * @example
379
     * ```
380
     * Carbon::parse('2018-07-25')->betweenIncluded('2018-07-14', '2018-08-01'); // true
381
     * Carbon::parse('2018-07-25')->betweenIncluded('2018-08-01', '2018-08-20'); // false
382
     * Carbon::parse('2018-07-25')->betweenIncluded('2018-07-25', '2018-08-01'); // true
383
     * ```
384
     *
385
     * @param \Carbon\Carbon|\DateTimeInterface|mixed $date1
386
     * @param \Carbon\Carbon|\DateTimeInterface|mixed $date2
387
     *
388
     * @return bool
389
     */
390
    public function betweenIncluded($date1, $date2): bool
391
    {
392
        return $this->between($date1, $date2, true);
393
    }
394
 
395
    /**
396
     * Determines if the instance is between two others, bounds excluded.
397
     *
398
     * @example
399
     * ```
400
     * Carbon::parse('2018-07-25')->betweenExcluded('2018-07-14', '2018-08-01'); // true
401
     * Carbon::parse('2018-07-25')->betweenExcluded('2018-08-01', '2018-08-20'); // false
402
     * Carbon::parse('2018-07-25')->betweenExcluded('2018-07-25', '2018-08-01'); // false
403
     * ```
404
     *
405
     * @param \Carbon\Carbon|\DateTimeInterface|mixed $date1
406
     * @param \Carbon\Carbon|\DateTimeInterface|mixed $date2
407
     *
408
     * @return bool
409
     */
410
    public function betweenExcluded($date1, $date2): bool
411
    {
412
        return $this->between($date1, $date2, false);
413
    }
414
 
415
    /**
416
     * Determines if the instance is between two others
417
     *
418
     * @example
419
     * ```
420
     * Carbon::parse('2018-07-25')->isBetween('2018-07-14', '2018-08-01'); // true
421
     * Carbon::parse('2018-07-25')->isBetween('2018-08-01', '2018-08-20'); // false
422
     * Carbon::parse('2018-07-25')->isBetween('2018-07-25', '2018-08-01'); // true
423
     * Carbon::parse('2018-07-25')->isBetween('2018-07-25', '2018-08-01', false); // false
424
     * ```
425
     *
426
     * @param \Carbon\Carbon|\DateTimeInterface|mixed $date1
427
     * @param \Carbon\Carbon|\DateTimeInterface|mixed $date2
428
     * @param bool                                    $equal Indicates if an equal to comparison should be done
429
     *
430
     * @return bool
431
     */
432
    public function isBetween($date1, $date2, $equal = true): bool
433
    {
434
        return $this->between($date1, $date2, $equal);
435
    }
436
 
437
    /**
438
     * Determines if the instance is a weekday.
439
     *
440
     * @example
441
     * ```
442
     * Carbon::parse('2019-07-14')->isWeekday(); // false
443
     * Carbon::parse('2019-07-15')->isWeekday(); // true
444
     * ```
445
     *
446
     * @return bool
447
     */
448
    public function isWeekday()
449
    {
450
        return !$this->isWeekend();
451
    }
452
 
453
    /**
454
     * Determines if the instance is a weekend day.
455
     *
456
     * @example
457
     * ```
458
     * Carbon::parse('2019-07-14')->isWeekend(); // true
459
     * Carbon::parse('2019-07-15')->isWeekend(); // false
460
     * ```
461
     *
462
     * @return bool
463
     */
464
    public function isWeekend()
465
    {
466
        return \in_array($this->dayOfWeek, static::$weekendDays, true);
467
    }
468
 
469
    /**
470
     * Determines if the instance is yesterday.
471
     *
472
     * @example
473
     * ```
474
     * Carbon::yesterday()->isYesterday(); // true
475
     * Carbon::tomorrow()->isYesterday(); // false
476
     * ```
477
     *
478
     * @return bool
479
     */
480
    public function isYesterday()
481
    {
482
        return $this->toDateString() === static::yesterday($this->getTimezone())->toDateString();
483
    }
484
 
485
    /**
486
     * Determines if the instance is today.
487
     *
488
     * @example
489
     * ```
490
     * Carbon::today()->isToday(); // true
491
     * Carbon::tomorrow()->isToday(); // false
492
     * ```
493
     *
494
     * @return bool
495
     */
496
    public function isToday()
497
    {
498
        return $this->toDateString() === $this->nowWithSameTz()->toDateString();
499
    }
500
 
501
    /**
502
     * Determines if the instance is tomorrow.
503
     *
504
     * @example
505
     * ```
506
     * Carbon::tomorrow()->isTomorrow(); // true
507
     * Carbon::yesterday()->isTomorrow(); // false
508
     * ```
509
     *
510
     * @return bool
511
     */
512
    public function isTomorrow()
513
    {
514
        return $this->toDateString() === static::tomorrow($this->getTimezone())->toDateString();
515
    }
516
 
517
    /**
518
     * Determines if the instance is in the future, ie. greater (after) than now.
519
     *
520
     * @example
521
     * ```
522
     * Carbon::now()->addHours(5)->isFuture(); // true
523
     * Carbon::now()->subHours(5)->isFuture(); // false
524
     * ```
525
     *
526
     * @return bool
527
     */
528
    public function isFuture()
529
    {
530
        return $this->greaterThan($this->nowWithSameTz());
531
    }
532
 
533
    /**
534
     * Determines if the instance is in the past, ie. less (before) than now.
535
     *
536
     * @example
537
     * ```
538
     * Carbon::now()->subHours(5)->isPast(); // true
539
     * Carbon::now()->addHours(5)->isPast(); // false
540
     * ```
541
     *
542
     * @return bool
543
     */
544
    public function isPast()
545
    {
546
        return $this->lessThan($this->nowWithSameTz());
547
    }
548
 
549
    /**
550
     * Determines if the instance is a leap year.
551
     *
552
     * @example
553
     * ```
554
     * Carbon::parse('2020-01-01')->isLeapYear(); // true
555
     * Carbon::parse('2019-01-01')->isLeapYear(); // false
556
     * ```
557
     *
558
     * @return bool
559
     */
560
    public function isLeapYear()
561
    {
562
        return $this->rawFormat('L') === '1';
563
    }
564
 
565
    /**
566
     * Determines if the instance is a long year (using calendar year).
567
     *
568
     * ⚠️ This method completely ignores month and day to use the numeric year number,
569
     * it's not correct if the exact date matters. For instance as `2019-12-30` is already
570
     * in the first week of the 2020 year, if you want to know from this date if ISO week
571
     * year 2020 is a long year, use `isLongIsoYear` instead.
572
     *
573
     * @example
574
     * ```
575
     * Carbon::create(2015)->isLongYear(); // true
576
     * Carbon::create(2016)->isLongYear(); // false
577
     * ```
578
     *
579
     * @see https://en.wikipedia.org/wiki/ISO_8601#Week_dates
580
     *
581
     * @return bool
582
     */
583
    public function isLongYear()
584
    {
585
        return static::create($this->year, 12, 28, 0, 0, 0, $this->tz)->weekOfYear === 53;
586
    }
587
 
588
    /**
589
     * Determines if the instance is a long year (using ISO 8601 year).
590
     *
591
     * @example
592
     * ```
593
     * Carbon::parse('2015-01-01')->isLongIsoYear(); // true
594
     * Carbon::parse('2016-01-01')->isLongIsoYear(); // true
595
     * Carbon::parse('2016-01-03')->isLongIsoYear(); // false
596
     * Carbon::parse('2019-12-29')->isLongIsoYear(); // false
597
     * Carbon::parse('2019-12-30')->isLongIsoYear(); // true
598
     * ```
599
     *
600
     * @see https://en.wikipedia.org/wiki/ISO_8601#Week_dates
601
     *
602
     * @return bool
603
     */
604
    public function isLongIsoYear()
605
    {
606
        return static::create($this->isoWeekYear, 12, 28, 0, 0, 0, $this->tz)->weekOfYear === 53;
607
    }
608
 
609
    /**
610
     * Compares the formatted values of the two dates.
611
     *
612
     * @example
613
     * ```
614
     * Carbon::parse('2019-06-13')->isSameAs('Y-d', Carbon::parse('2019-12-13')); // true
615
     * Carbon::parse('2019-06-13')->isSameAs('Y-d', Carbon::parse('2019-06-14')); // false
616
     * ```
617
     *
618
     * @param string                                        $format date formats to compare.
619
     * @param \Carbon\Carbon|\DateTimeInterface|string|null $date   instance to compare with or null to use current day.
620
     *
621
     * @return bool
622
     */
623
    public function isSameAs($format, $date = null)
624
    {
625
        return $this->rawFormat($format) === $this->resolveCarbon($date)->rawFormat($format);
626
    }
627
 
628
    /**
629
     * Determines if the instance is in the current unit given.
630
     *
631
     * @example
632
     * ```
633
     * Carbon::parse('2019-01-13')->isSameUnit('year', Carbon::parse('2019-12-25')); // true
634
     * Carbon::parse('2018-12-13')->isSameUnit('year', Carbon::parse('2019-12-25')); // false
635
     * ```
636
     *
637
     * @param string                                 $unit singular unit string
638
     * @param \Carbon\Carbon|\DateTimeInterface|null $date instance to compare with or null to use current day.
639
     *
640
     * @throws BadComparisonUnitException
641
     *
642
     * @return bool
643
     */
644
    public function isSameUnit($unit, $date = null)
645
    {
646
        $units = [
647
            // @call isSameUnit
648
            'year' => 'Y',
649
            // @call isSameUnit
650
            'week' => 'o-W',
651
            // @call isSameUnit
652
            'day' => 'Y-m-d',
653
            // @call isSameUnit
654
            'hour' => 'Y-m-d H',
655
            // @call isSameUnit
656
            'minute' => 'Y-m-d H:i',
657
            // @call isSameUnit
658
            'second' => 'Y-m-d H:i:s',
659
            // @call isSameUnit
660
            'micro' => 'Y-m-d H:i:s.u',
661
            // @call isSameUnit
662
            'microsecond' => 'Y-m-d H:i:s.u',
663
        ];
664
 
665
        if (isset($units[$unit])) {
666
            return $this->isSameAs($units[$unit], $date);
667
        }
668
 
669
        if (isset($this->$unit)) {
670
            return $this->resolveCarbon($date)->$unit === $this->$unit;
671
        }
672
 
673
        if ($this->localStrictModeEnabled ?? static::isStrictModeEnabled()) {
674
            throw new BadComparisonUnitException($unit);
675
        }
676
 
677
        return false;
678
    }
679
 
680
    /**
681
     * Determines if the instance is in the current unit given.
682
     *
683
     * @example
684
     * ```
685
     * Carbon::now()->isCurrentUnit('hour'); // true
686
     * Carbon::now()->subHours(2)->isCurrentUnit('hour'); // false
687
     * ```
688
     *
689
     * @param string $unit The unit to test.
690
     *
691
     * @throws BadMethodCallException
692
     *
693
     * @return bool
694
     */
695
    public function isCurrentUnit($unit)
696
    {
697
        return $this->{'isSame'.ucfirst($unit)}();
698
    }
699
 
700
    /**
701
     * Checks if the passed in date is in the same quarter as the instance quarter (and year if needed).
702
     *
703
     * @example
704
     * ```
705
     * Carbon::parse('2019-01-12')->isSameQuarter(Carbon::parse('2019-03-01')); // true
706
     * Carbon::parse('2019-01-12')->isSameQuarter(Carbon::parse('2019-04-01')); // false
707
     * Carbon::parse('2019-01-12')->isSameQuarter(Carbon::parse('2018-03-01')); // false
708
     * Carbon::parse('2019-01-12')->isSameQuarter(Carbon::parse('2018-03-01'), false); // true
709
     * ```
710
     *
711
     * @param \Carbon\Carbon|\DateTimeInterface|string|null $date       The instance to compare with or null to use current day.
712
     * @param bool                                          $ofSameYear Check if it is the same month in the same year.
713
     *
714
     * @return bool
715
     */
716
    public function isSameQuarter($date = null, $ofSameYear = true)
717
    {
718
        $date = $this->resolveCarbon($date);
719
 
720
        return $this->quarter === $date->quarter && (!$ofSameYear || $this->isSameYear($date));
721
    }
722
 
723
    /**
724
     * Checks if the passed in date is in the same month as the instance´s month.
725
     *
726
     * @example
727
     * ```
728
     * Carbon::parse('2019-01-12')->isSameMonth(Carbon::parse('2019-01-01')); // true
729
     * Carbon::parse('2019-01-12')->isSameMonth(Carbon::parse('2019-02-01')); // false
730
     * Carbon::parse('2019-01-12')->isSameMonth(Carbon::parse('2018-01-01')); // false
731
     * Carbon::parse('2019-01-12')->isSameMonth(Carbon::parse('2018-01-01'), false); // true
732
     * ```
733
     *
734
     * @param \Carbon\Carbon|\DateTimeInterface|null $date       The instance to compare with or null to use the current date.
735
     * @param bool                                   $ofSameYear Check if it is the same month in the same year.
736
     *
737
     * @return bool
738
     */
739
    public function isSameMonth($date = null, $ofSameYear = true)
740
    {
741
        return $this->isSameAs($ofSameYear ? 'Y-m' : 'm', $date);
742
    }
743
 
744
    /**
745
     * Checks if this day is a specific day of the week.
746
     *
747
     * @example
748
     * ```
749
     * Carbon::parse('2019-07-17')->isDayOfWeek(Carbon::WEDNESDAY); // true
750
     * Carbon::parse('2019-07-17')->isDayOfWeek(Carbon::FRIDAY); // false
751
     * Carbon::parse('2019-07-17')->isDayOfWeek('Wednesday'); // true
752
     * Carbon::parse('2019-07-17')->isDayOfWeek('Friday'); // false
753
     * ```
754
     *
755
     * @param int $dayOfWeek
756
     *
757
     * @return bool
758
     */
759
    public function isDayOfWeek($dayOfWeek)
760
    {
761
        if (\is_string($dayOfWeek) && \defined($constant = static::class.'::'.strtoupper($dayOfWeek))) {
762
            $dayOfWeek = \constant($constant);
763
        }
764
 
765
        return $this->dayOfWeek === $dayOfWeek;
766
    }
767
 
768
    /**
769
     * Check if its the birthday. Compares the date/month values of the two dates.
770
     *
771
     * @example
772
     * ```
773
     * Carbon::now()->subYears(5)->isBirthday(); // true
774
     * Carbon::now()->subYears(5)->subDay()->isBirthday(); // false
775
     * Carbon::parse('2019-06-05')->isBirthday(Carbon::parse('2001-06-05')); // true
776
     * Carbon::parse('2019-06-05')->isBirthday(Carbon::parse('2001-06-06')); // false
777
     * ```
778
     *
779
     * @param \Carbon\Carbon|\DateTimeInterface|null $date The instance to compare with or null to use current day.
780
     *
781
     * @return bool
782
     */
783
    public function isBirthday($date = null)
784
    {
785
        return $this->isSameAs('md', $date);
786
    }
787
 
788
    /**
789
     * Check if today is the last day of the Month
790
     *
791
     * @example
792
     * ```
793
     * Carbon::parse('2019-02-28')->isLastOfMonth(); // true
794
     * Carbon::parse('2019-03-28')->isLastOfMonth(); // false
795
     * Carbon::parse('2019-03-30')->isLastOfMonth(); // false
796
     * Carbon::parse('2019-03-31')->isLastOfMonth(); // true
797
     * Carbon::parse('2019-04-30')->isLastOfMonth(); // true
798
     * ```
799
     *
800
     * @return bool
801
     */
802
    public function isLastOfMonth()
803
    {
804
        return $this->day === $this->daysInMonth;
805
    }
806
 
807
    /**
808
     * Check if the instance is start of day / midnight.
809
     *
810
     * @example
811
     * ```
812
     * Carbon::parse('2019-02-28 00:00:00')->isStartOfDay(); // true
813
     * Carbon::parse('2019-02-28 00:00:00.999999')->isStartOfDay(); // true
814
     * Carbon::parse('2019-02-28 00:00:01')->isStartOfDay(); // false
815
     * Carbon::parse('2019-02-28 00:00:00.000000')->isStartOfDay(true); // true
816
     * Carbon::parse('2019-02-28 00:00:00.000012')->isStartOfDay(true); // false
817
     * ```
818
     *
819
     * @param bool $checkMicroseconds check time at microseconds precision
820
     *
821
     * @return bool
822
     */
823
    public function isStartOfDay($checkMicroseconds = false)
824
    {
825
        /* @var CarbonInterface $this */
826
        return $checkMicroseconds
827
            ? $this->rawFormat('H:i:s.u') === '00:00:00.000000'
828
            : $this->rawFormat('H:i:s') === '00:00:00';
829
    }
830
 
831
    /**
832
     * Check if the instance is end of day.
833
     *
834
     * @example
835
     * ```
836
     * Carbon::parse('2019-02-28 23:59:59.999999')->isEndOfDay(); // true
837
     * Carbon::parse('2019-02-28 23:59:59.123456')->isEndOfDay(); // true
838
     * Carbon::parse('2019-02-28 23:59:59')->isEndOfDay(); // true
839
     * Carbon::parse('2019-02-28 23:59:58.999999')->isEndOfDay(); // false
840
     * Carbon::parse('2019-02-28 23:59:59.999999')->isEndOfDay(true); // true
841
     * Carbon::parse('2019-02-28 23:59:59.123456')->isEndOfDay(true); // false
842
     * Carbon::parse('2019-02-28 23:59:59')->isEndOfDay(true); // false
843
     * ```
844
     *
845
     * @param bool $checkMicroseconds check time at microseconds precision
846
     *
847
     * @return bool
848
     */
849
    public function isEndOfDay($checkMicroseconds = false)
850
    {
851
        /* @var CarbonInterface $this */
852
        return $checkMicroseconds
853
            ? $this->rawFormat('H:i:s.u') === '23:59:59.999999'
854
            : $this->rawFormat('H:i:s') === '23:59:59';
855
    }
856
 
857
    /**
858
     * Check if the instance is start of day / midnight.
859
     *
860
     * @example
861
     * ```
862
     * Carbon::parse('2019-02-28 00:00:00')->isMidnight(); // true
863
     * Carbon::parse('2019-02-28 00:00:00.999999')->isMidnight(); // true
864
     * Carbon::parse('2019-02-28 00:00:01')->isMidnight(); // false
865
     * ```
866
     *
867
     * @return bool
868
     */
869
    public function isMidnight()
870
    {
871
        return $this->isStartOfDay();
872
    }
873
 
874
    /**
875
     * Check if the instance is midday.
876
     *
877
     * @example
878
     * ```
879
     * Carbon::parse('2019-02-28 11:59:59.999999')->isMidday(); // false
880
     * Carbon::parse('2019-02-28 12:00:00')->isMidday(); // true
881
     * Carbon::parse('2019-02-28 12:00:00.999999')->isMidday(); // true
882
     * Carbon::parse('2019-02-28 12:00:01')->isMidday(); // false
883
     * ```
884
     *
885
     * @return bool
886
     */
887
    public function isMidday()
888
    {
889
        /* @var CarbonInterface $this */
890
        return $this->rawFormat('G:i:s') === static::$midDayAt.':00:00';
891
    }
892
 
893
    /**
894
     * Checks if the (date)time string is in a given format.
895
     *
896
     * @example
897
     * ```
898
     * Carbon::hasFormat('11:12:45', 'h:i:s'); // true
899
     * Carbon::hasFormat('13:12:45', 'h:i:s'); // false
900
     * ```
901
     *
902
     * @param string $date
903
     * @param string $format
904
     *
905
     * @return bool
906
     */
907
    public static function hasFormat($date, $format)
908
    {
909
        // createFromFormat() is known to handle edge cases silently.
910
        // E.g. "1975-5-1" (Y-n-j) will still be parsed correctly when "Y-m-d" is supplied as the format.
911
        // To ensure we're really testing against our desired format, perform an additional regex validation.
912
 
913
        return self::matchFormatPattern((string) $date, preg_quote((string) $format, '/'), static::$regexFormats);
914
    }
915
 
916
    /**
917
     * Checks if the (date)time string is in a given format.
918
     *
919
     * @example
920
     * ```
921
     * Carbon::hasFormatWithModifiers('31/08/2015', 'd#m#Y'); // true
922
     * Carbon::hasFormatWithModifiers('31/08/2015', 'm#d#Y'); // false
923
     * ```
924
     *
925
     * @param string $date
926
     * @param string $format
927
     *
928
     * @return bool
929
     */
930
    public static function hasFormatWithModifiers($date, $format): bool
931
    {
932
        return self::matchFormatPattern((string) $date, (string) $format, array_merge(static::$regexFormats, static::$regexFormatModifiers));
933
    }
934
 
935
    /**
936
     * Checks if the (date)time string is in a given format and valid to create a
937
     * new instance.
938
     *
939
     * @example
940
     * ```
941
     * Carbon::canBeCreatedFromFormat('11:12:45', 'h:i:s'); // true
942
     * Carbon::canBeCreatedFromFormat('13:12:45', 'h:i:s'); // false
943
     * ```
944
     *
945
     * @param string $date
946
     * @param string $format
947
     *
948
     * @return bool
949
     */
950
    public static function canBeCreatedFromFormat($date, $format)
951
    {
952
        try {
953
            // Try to create a DateTime object. Throws an InvalidArgumentException if the provided time string
954
            // doesn't match the format in any way.
955
            if (!static::rawCreateFromFormat($format, $date)) {
956
                return false;
957
            }
958
        } catch (InvalidArgumentException $e) {
959
            return false;
960
        }
961
 
962
        return static::hasFormatWithModifiers($date, $format);
963
    }
964
 
965
    /**
966
     * Returns true if the current date matches the given string.
967
     *
968
     * @example
969
     * ```
970
     * var_dump(Carbon::parse('2019-06-02 12:23:45')->is('2019')); // true
971
     * var_dump(Carbon::parse('2019-06-02 12:23:45')->is('2018')); // false
972
     * var_dump(Carbon::parse('2019-06-02 12:23:45')->is('2019-06')); // true
973
     * var_dump(Carbon::parse('2019-06-02 12:23:45')->is('06-02')); // true
974
     * var_dump(Carbon::parse('2019-06-02 12:23:45')->is('2019-06-02')); // true
975
     * var_dump(Carbon::parse('2019-06-02 12:23:45')->is('Sunday')); // true
976
     * var_dump(Carbon::parse('2019-06-02 12:23:45')->is('June')); // true
977
     * var_dump(Carbon::parse('2019-06-02 12:23:45')->is('12:23')); // true
978
     * var_dump(Carbon::parse('2019-06-02 12:23:45')->is('12:23:45')); // true
979
     * var_dump(Carbon::parse('2019-06-02 12:23:45')->is('12:23:00')); // false
980
     * var_dump(Carbon::parse('2019-06-02 12:23:45')->is('12h')); // true
981
     * var_dump(Carbon::parse('2019-06-02 15:23:45')->is('3pm')); // true
982
     * var_dump(Carbon::parse('2019-06-02 15:23:45')->is('3am')); // false
983
     * ```
984
     *
985
     * @param string $tester day name, month name, hour, date, etc. as string
986
     *
987
     * @return bool
988
     */
989
    public function is(string $tester)
990
    {
991
        $tester = trim($tester);
992
 
993
        if (preg_match('/^\d+$/', $tester)) {
994
            return $this->year === (int) $tester;
995
        }
996
 
997
        if (preg_match('/^\d{3,}-\d{1,2}$/', $tester)) {
998
            return $this->isSameMonth(static::parse($tester));
999
        }
1000
 
1001
        if (preg_match('/^\d{1,2}-\d{1,2}$/', $tester)) {
1002
            return $this->isSameDay(static::parse($this->year.'-'.$tester));
1003
        }
1004
 
1005
        $modifier = preg_replace('/(\d)h$/i', '$1:00', $tester);
1006
 
1007
        /* @var CarbonInterface $max */
1008
        $median = static::parse('5555-06-15 12:30:30.555555')->modify($modifier);
1009
        $current = $this->avoidMutation();
1010
        /* @var CarbonInterface $other */
1011
        $other = $this->avoidMutation()->modify($modifier);
1012
 
1013
        if ($current->eq($other)) {
1014
            return true;
1015
        }
1016
 
1017
        if (preg_match('/\d:\d{1,2}:\d{1,2}$/', $tester)) {
1018
            return $current->startOfSecond()->eq($other);
1019
        }
1020
 
1021
        if (preg_match('/\d:\d{1,2}$/', $tester)) {
1022
            return $current->startOfMinute()->eq($other);
1023
        }
1024
 
1025
        if (preg_match('/\d(h|am|pm)$/', $tester)) {
1026
            return $current->startOfHour()->eq($other);
1027
        }
1028
 
1029
        if (preg_match(
1030
            '/^(january|february|march|april|may|june|july|august|september|october|november|december)\s+\d+$/i',
1031
            $tester
1032
        )) {
1033
            return $current->startOfMonth()->eq($other->startOfMonth());
1034
        }
1035
 
1036
        $units = [
1037
            'month' => [1, 'year'],
1038
            'day' => [1, 'month'],
1039
            'hour' => [0, 'day'],
1040
            'minute' => [0, 'hour'],
1041
            'second' => [0, 'minute'],
1042
            'microsecond' => [0, 'second'],
1043
        ];
1044
 
1045
        foreach ($units as $unit => [$minimum, $startUnit]) {
1046
            if ($minimum === $median->$unit) {
1047
                $current = $current->startOf($startUnit);
1048
 
1049
                break;
1050
            }
1051
        }
1052
 
1053
        return $current->eq($other);
1054
    }
1055
 
1056
    /**
1057
     * Checks if the (date)time string is in a given format with
1058
     * given list of pattern replacements.
1059
     *
1060
     * @example
1061
     * ```
1062
     * Carbon::hasFormat('11:12:45', 'h:i:s'); // true
1063
     * Carbon::hasFormat('13:12:45', 'h:i:s'); // false
1064
     * ```
1065
     *
1066
     * @param string $date
1067
     * @param string $format
1068
     * @param array  $replacements
1069
     *
1070
     * @return bool
1071
     */
1072
    private static function matchFormatPattern(string $date, string $format, array $replacements): bool
1073
    {
1074
        // Preg quote, but remove escaped backslashes since we'll deal with escaped characters in the format string.
1075
        $regex = str_replace('\\\\', '\\', $format);
1076
        // Replace not-escaped letters
1077
        $regex = preg_replace_callback(
1078
            '/(?<!\\\\)((?:\\\\{2})*)(['.implode('', array_keys($replacements)).'])/',
1079
            function ($match) use ($replacements) {
1080
                return $match[1].strtr($match[2], $replacements);
1081
            },
1082
            $regex
1083
        );
1084
        // Replace escaped letters by the letter itself
1085
        $regex = preg_replace('/(?<!\\\\)((?:\\\\{2})*)\\\\(\w)/', '$1$2', $regex);
1086
        // Escape not escaped slashes
1087
        $regex = preg_replace('#(?<!\\\\)((?:\\\\{2})*)/#', '$1\\/', $regex);
1088
 
1089
        return (bool) @preg_match('/^'.$regex.'$/', $date);
1090
    }
1091
 
1092
    /**
1093
     * Returns true if the date was created using CarbonImmutable::startOfTime()
1094
     *
1095
     * @return bool
1096
     */
1097
    public function isStartOfTime(): bool
1098
    {
1099
        return $this->startOfTime ?? false;
1100
    }
1101
 
1102
    /**
1103
     * Returns true if the date was created using CarbonImmutable::endOfTime()
1104
     *
1105
     * @return bool
1106
     */
1107
    public function isEndOfTime(): bool
1108
    {
1109
        return $this->endOfTime ?? false;
1110
    }
1111
 
1112
    private function discourageNull($value): void
1113
    {
1114
        if ($value === null) {
1115
            @trigger_error("Since 2.61.0, it's deprecated to compare a date to null, meaning of such comparison is ambiguous and will no longer be possible in 3.0.0, you should explicitly pass 'now' or make an other check to eliminate null values.", \E_USER_DEPRECATED);
1116
        }
1117
    }
1118
 
1119
    private function discourageBoolean($value): void
1120
    {
1121
        if (\is_bool($value)) {
1122
            @trigger_error("Since 2.61.0, it's deprecated to compare a date to true or false, meaning of such comparison is ambiguous and will no longer be possible in 3.0.0, you should explicitly pass 'now' or make an other check to eliminate boolean values.", \E_USER_DEPRECATED);
1123
        }
1124
    }
1125
}