Subversion-Projekte lars-tiefland.laravel_shop

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 Carbon\Carbon;
15
use Carbon\CarbonImmutable;
16
use Carbon\CarbonInterface;
17
use Carbon\CarbonInterval;
18
use Carbon\CarbonPeriod;
19
use Carbon\Translator;
20
use Closure;
21
use DateInterval;
22
use DateTimeInterface;
23
use ReturnTypeWillChange;
24
 
25
/**
26
 * Trait Difference.
27
 *
28
 * Depends on the following methods:
29
 *
30
 * @method bool lessThan($date)
31
 * @method static copy()
32
 * @method static resolveCarbon($date = null)
33
 * @method static Translator translator()
34
 */
35
trait Difference
36
{
37
    /**
38
     * @codeCoverageIgnore
39
     *
40
     * @param CarbonInterval $diff
41
     */
42
    protected static function fixNegativeMicroseconds(CarbonInterval $diff)
43
    {
44
        if ($diff->s !== 0 || $diff->i !== 0 || $diff->h !== 0 || $diff->d !== 0 || $diff->m !== 0 || $diff->y !== 0) {
45
            $diff->f = (round($diff->f * 1000000) + 1000000) / 1000000;
46
            $diff->s--;
47
 
48
            if ($diff->s < 0) {
49
                $diff->s += 60;
50
                $diff->i--;
51
 
52
                if ($diff->i < 0) {
53
                    $diff->i += 60;
54
                    $diff->h--;
55
 
56
                    if ($diff->h < 0) {
57
                        $diff->h += 24;
58
                        $diff->d--;
59
 
60
                        if ($diff->d < 0) {
61
                            $diff->d += 30;
62
                            $diff->m--;
63
 
64
                            if ($diff->m < 0) {
65
                                $diff->m += 12;
66
                                $diff->y--;
67
                            }
68
                        }
69
                    }
70
                }
71
            }
72
 
73
            return;
74
        }
75
 
76
        $diff->f *= -1;
77
        $diff->invert();
78
    }
79
 
80
    /**
81
     * @param DateInterval $diff
82
     * @param bool         $absolute
83
     *
84
     * @return CarbonInterval
85
     */
86
    protected static function fixDiffInterval(DateInterval $diff, $absolute, array $skip = [])
87
    {
88
        $diff = CarbonInterval::instance($diff, $skip);
89
 
90
        // Work-around for https://bugs.php.net/bug.php?id=77145
91
        // @codeCoverageIgnoreStart
92
        if ($diff->f > 0 && $diff->y === -1 && $diff->m === 11 && $diff->d >= 27 && $diff->h === 23 && $diff->i === 59 && $diff->s === 59) {
93
            $diff->y = 0;
94
            $diff->m = 0;
95
            $diff->d = 0;
96
            $diff->h = 0;
97
            $diff->i = 0;
98
            $diff->s = 0;
99
            $diff->f = (1000000 - round($diff->f * 1000000)) / 1000000;
100
            $diff->invert();
101
        } elseif ($diff->f < 0) {
102
            static::fixNegativeMicroseconds($diff);
103
        }
104
        // @codeCoverageIgnoreEnd
105
 
106
        if ($absolute && $diff->invert) {
107
            $diff->invert();
108
        }
109
 
110
        return $diff;
111
    }
112
 
113
    /**
114
     * Get the difference as a DateInterval instance.
115
     * Return relative interval (negative if $absolute flag is not set to true and the given date is before
116
     * current one).
117
     *
118
     * @param \Carbon\CarbonInterface|\DateTimeInterface|string|null $date
119
     * @param bool                                                   $absolute Get the absolute of the difference
120
     *
121
     * @return DateInterval
122
     */
123
    #[ReturnTypeWillChange]
124
    public function diff($date = null, $absolute = false)
125
    {
126
        $other = $this->resolveCarbon($date);
127
 
128
        // Work-around for https://bugs.php.net/bug.php?id=81458
129
        // It was initially introduced for https://bugs.php.net/bug.php?id=80998
130
        // The very specific case of 80998 was fixed in PHP 8.1beta3, but it introduced 81458
131
        // So we still need to keep this for now
132
        // @codeCoverageIgnoreStart
133
        if (version_compare(PHP_VERSION, '8.1.0-dev', '>=') && $other->tz !== $this->tz) {
134
            $other = $other->avoidMutation()->tz($this->tz);
135
        }
136
        // @codeCoverageIgnoreEnd
137
 
138
        return parent::diff($other, (bool) $absolute);
139
    }
140
 
141
    /**
142
     * Get the difference as a CarbonInterval instance.
143
     * Return relative interval (negative if $absolute flag is not set to true and the given date is before
144
     * current one).
145
     *
146
     * @param \Carbon\CarbonInterface|\DateTimeInterface|string|null $date
147
     * @param bool                                                   $absolute Get the absolute of the difference
148
     *
149
     * @return CarbonInterval
150
     */
151
    public function diffAsCarbonInterval($date = null, $absolute = true, array $skip = [])
152
    {
153
        return static::fixDiffInterval($this->diff($this->resolveCarbon($date), $absolute), $absolute, $skip);
154
    }
155
 
156
    /**
157
     * Get the difference in years
158
     *
159
     * @param \Carbon\CarbonInterface|\DateTimeInterface|string|null $date
160
     * @param bool                                                   $absolute Get the absolute of the difference
161
     *
162
     * @return int
163
     */
164
    public function diffInYears($date = null, $absolute = true)
165
    {
166
        return (int) $this->diff($this->resolveCarbon($date), $absolute)->format('%r%y');
167
    }
168
 
169
    /**
170
     * Get the difference in quarters rounded down.
171
     *
172
     * @param \Carbon\CarbonInterface|\DateTimeInterface|string|null $date
173
     * @param bool                                                   $absolute Get the absolute of the difference
174
     *
175
     * @return int
176
     */
177
    public function diffInQuarters($date = null, $absolute = true)
178
    {
179
        return (int) ($this->diffInMonths($date, $absolute) / static::MONTHS_PER_QUARTER);
180
    }
181
 
182
    /**
183
     * Get the difference in months rounded down.
184
     *
185
     * @param \Carbon\CarbonInterface|\DateTimeInterface|string|null $date
186
     * @param bool                                                   $absolute Get the absolute of the difference
187
     *
188
     * @return int
189
     */
190
    public function diffInMonths($date = null, $absolute = true)
191
    {
192
        $date = $this->resolveCarbon($date)->avoidMutation()->tz($this->tz);
193
 
194
        [$yearStart, $monthStart, $dayStart] = explode('-', $this->format('Y-m-dHisu'));
195
        [$yearEnd, $monthEnd, $dayEnd] = explode('-', $date->format('Y-m-dHisu'));
196
 
197
        $diff = (((int) $yearEnd) - ((int) $yearStart)) * static::MONTHS_PER_YEAR +
198
            ((int) $monthEnd) - ((int) $monthStart);
199
 
200
        if ($diff > 0) {
201
            $diff -= ($dayStart > $dayEnd ? 1 : 0);
202
        } elseif ($diff < 0) {
203
            $diff += ($dayStart < $dayEnd ? 1 : 0);
204
        }
205
 
206
        return $absolute ? abs($diff) : $diff;
207
    }
208
 
209
    /**
210
     * Get the difference in weeks rounded down.
211
     *
212
     * @param \Carbon\CarbonInterface|\DateTimeInterface|string|null $date
213
     * @param bool                                                   $absolute Get the absolute of the difference
214
     *
215
     * @return int
216
     */
217
    public function diffInWeeks($date = null, $absolute = true)
218
    {
219
        return (int) ($this->diffInDays($date, $absolute) / static::DAYS_PER_WEEK);
220
    }
221
 
222
    /**
223
     * Get the difference in days rounded down.
224
     *
225
     * @param \Carbon\CarbonInterface|\DateTimeInterface|string|null $date
226
     * @param bool                                                   $absolute Get the absolute of the difference
227
     *
228
     * @return int
229
     */
230
    public function diffInDays($date = null, $absolute = true)
231
    {
232
        return $this->getIntervalDayDiff($this->diff($this->resolveCarbon($date), $absolute));
233
    }
234
 
235
    /**
236
     * Get the difference in days using a filter closure rounded down.
237
     *
238
     * @param Closure                                                $callback
239
     * @param \Carbon\CarbonInterface|\DateTimeInterface|string|null $date
240
     * @param bool                                                   $absolute Get the absolute of the difference
241
     *
242
     * @return int
243
     */
244
    public function diffInDaysFiltered(Closure $callback, $date = null, $absolute = true)
245
    {
246
        return $this->diffFiltered(CarbonInterval::day(), $callback, $date, $absolute);
247
    }
248
 
249
    /**
250
     * Get the difference in hours using a filter closure rounded down.
251
     *
252
     * @param Closure                                                $callback
253
     * @param \Carbon\CarbonInterface|\DateTimeInterface|string|null $date
254
     * @param bool                                                   $absolute Get the absolute of the difference
255
     *
256
     * @return int
257
     */
258
    public function diffInHoursFiltered(Closure $callback, $date = null, $absolute = true)
259
    {
260
        return $this->diffFiltered(CarbonInterval::hour(), $callback, $date, $absolute);
261
    }
262
 
263
    /**
264
     * Get the difference by the given interval using a filter closure.
265
     *
266
     * @param CarbonInterval                                         $ci       An interval to traverse by
267
     * @param Closure                                                $callback
268
     * @param \Carbon\CarbonInterface|\DateTimeInterface|string|null $date
269
     * @param bool                                                   $absolute Get the absolute of the difference
270
     *
271
     * @return int
272
     */
273
    public function diffFiltered(CarbonInterval $ci, Closure $callback, $date = null, $absolute = true)
274
    {
275
        $start = $this;
276
        $end = $this->resolveCarbon($date);
277
        $inverse = false;
278
 
279
        if ($end < $start) {
280
            $start = $end;
281
            $end = $this;
282
            $inverse = true;
283
        }
284
 
285
        $options = CarbonPeriod::EXCLUDE_END_DATE | ($this->isMutable() ? 0 : CarbonPeriod::IMMUTABLE);
286
        $diff = $ci->toPeriod($start, $end, $options)->filter($callback)->count();
287
 
288
        return $inverse && !$absolute ? -$diff : $diff;
289
    }
290
 
291
    /**
292
     * Get the difference in weekdays rounded down.
293
     *
294
     * @param \Carbon\CarbonInterface|\DateTimeInterface|string|null $date
295
     * @param bool                                                   $absolute Get the absolute of the difference
296
     *
297
     * @return int
298
     */
299
    public function diffInWeekdays($date = null, $absolute = true)
300
    {
301
        return $this->diffInDaysFiltered(function (CarbonInterface $date) {
302
            return $date->isWeekday();
303
        }, $date, $absolute);
304
    }
305
 
306
    /**
307
     * Get the difference in weekend days using a filter rounded down.
308
     *
309
     * @param \Carbon\CarbonInterface|\DateTimeInterface|string|null $date
310
     * @param bool                                                   $absolute Get the absolute of the difference
311
     *
312
     * @return int
313
     */
314
    public function diffInWeekendDays($date = null, $absolute = true)
315
    {
316
        return $this->diffInDaysFiltered(function (CarbonInterface $date) {
317
            return $date->isWeekend();
318
        }, $date, $absolute);
319
    }
320
 
321
    /**
322
     * Get the difference in hours rounded down.
323
     *
324
     * @param \Carbon\CarbonInterface|\DateTimeInterface|string|null $date
325
     * @param bool                                                   $absolute Get the absolute of the difference
326
     *
327
     * @return int
328
     */
329
    public function diffInHours($date = null, $absolute = true)
330
    {
331
        return (int) ($this->diffInSeconds($date, $absolute) / static::SECONDS_PER_MINUTE / static::MINUTES_PER_HOUR);
332
    }
333
 
334
    /**
335
     * Get the difference in hours rounded down using timestamps.
336
     *
337
     * @param \Carbon\CarbonInterface|\DateTimeInterface|string|null $date
338
     * @param bool                                                   $absolute Get the absolute of the difference
339
     *
340
     * @return int
341
     */
342
    public function diffInRealHours($date = null, $absolute = true)
343
    {
344
        return (int) ($this->diffInRealSeconds($date, $absolute) / static::SECONDS_PER_MINUTE / static::MINUTES_PER_HOUR);
345
    }
346
 
347
    /**
348
     * Get the difference in minutes rounded down.
349
     *
350
     * @param \Carbon\CarbonInterface|\DateTimeInterface|string|null $date
351
     * @param bool                                                   $absolute Get the absolute of the difference
352
     *
353
     * @return int
354
     */
355
    public function diffInMinutes($date = null, $absolute = true)
356
    {
357
        return (int) ($this->diffInSeconds($date, $absolute) / static::SECONDS_PER_MINUTE);
358
    }
359
 
360
    /**
361
     * Get the difference in minutes rounded down using timestamps.
362
     *
363
     * @param \Carbon\CarbonInterface|\DateTimeInterface|string|null $date
364
     * @param bool                                                   $absolute Get the absolute of the difference
365
     *
366
     * @return int
367
     */
368
    public function diffInRealMinutes($date = null, $absolute = true)
369
    {
370
        return (int) ($this->diffInRealSeconds($date, $absolute) / static::SECONDS_PER_MINUTE);
371
    }
372
 
373
    /**
374
     * Get the difference in seconds rounded down.
375
     *
376
     * @param \Carbon\CarbonInterface|\DateTimeInterface|string|null $date
377
     * @param bool                                                   $absolute Get the absolute of the difference
378
     *
379
     * @return int
380
     */
381
    public function diffInSeconds($date = null, $absolute = true)
382
    {
383
        $diff = $this->diff($date);
384
 
385
        if ($diff->days === 0) {
386
            $diff = static::fixDiffInterval($diff, $absolute);
387
        }
388
 
389
        $value = (((($diff->m || $diff->y ? $diff->days : $diff->d) * static::HOURS_PER_DAY) +
390
            $diff->h) * static::MINUTES_PER_HOUR +
391
            $diff->i) * static::SECONDS_PER_MINUTE +
392
            $diff->s;
393
 
394
        return $absolute || !$diff->invert ? $value : -$value;
395
    }
396
 
397
    /**
398
     * Get the difference in microseconds.
399
     *
400
     * @param \Carbon\CarbonInterface|\DateTimeInterface|string|null $date
401
     * @param bool                                                   $absolute Get the absolute of the difference
402
     *
403
     * @return int
404
     */
405
    public function diffInMicroseconds($date = null, $absolute = true)
406
    {
407
        $diff = $this->diff($date);
408
        $value = (int) round(((((($diff->m || $diff->y ? $diff->days : $diff->d) * static::HOURS_PER_DAY) +
409
            $diff->h) * static::MINUTES_PER_HOUR +
410
            $diff->i) * static::SECONDS_PER_MINUTE +
411
            ($diff->f + $diff->s)) * static::MICROSECONDS_PER_SECOND);
412
 
413
        return $absolute || !$diff->invert ? $value : -$value;
414
    }
415
 
416
    /**
417
     * Get the difference in milliseconds rounded down.
418
     *
419
     * @param \Carbon\CarbonInterface|\DateTimeInterface|string|null $date
420
     * @param bool                                                   $absolute Get the absolute of the difference
421
     *
422
     * @return int
423
     */
424
    public function diffInMilliseconds($date = null, $absolute = true)
425
    {
426
        return (int) ($this->diffInMicroseconds($date, $absolute) / static::MICROSECONDS_PER_MILLISECOND);
427
    }
428
 
429
    /**
430
     * Get the difference in seconds using timestamps.
431
     *
432
     * @param \Carbon\CarbonInterface|\DateTimeInterface|string|null $date
433
     * @param bool                                                   $absolute Get the absolute of the difference
434
     *
435
     * @return int
436
     */
437
    public function diffInRealSeconds($date = null, $absolute = true)
438
    {
439
        /** @var CarbonInterface $date */
440
        $date = $this->resolveCarbon($date);
441
        $value = $date->getTimestamp() - $this->getTimestamp();
442
 
443
        return $absolute ? abs($value) : $value;
444
    }
445
 
446
    /**
447
     * Get the difference in microseconds using timestamps.
448
     *
449
     * @param \Carbon\CarbonInterface|\DateTimeInterface|string|null $date
450
     * @param bool                                                   $absolute Get the absolute of the difference
451
     *
452
     * @return int
453
     */
454
    public function diffInRealMicroseconds($date = null, $absolute = true)
455
    {
456
        /** @var CarbonInterface $date */
457
        $date = $this->resolveCarbon($date);
458
        $value = ($date->timestamp - $this->timestamp) * static::MICROSECONDS_PER_SECOND +
459
            $date->micro - $this->micro;
460
 
461
        return $absolute ? abs($value) : $value;
462
    }
463
 
464
    /**
465
     * Get the difference in milliseconds rounded down using timestamps.
466
     *
467
     * @param \Carbon\CarbonInterface|\DateTimeInterface|string|null $date
468
     * @param bool                                                   $absolute Get the absolute of the difference
469
     *
470
     * @return int
471
     */
472
    public function diffInRealMilliseconds($date = null, $absolute = true)
473
    {
474
        return (int) ($this->diffInRealMicroseconds($date, $absolute) / static::MICROSECONDS_PER_MILLISECOND);
475
    }
476
 
477
    /**
478
     * Get the difference in seconds as float (microsecond-precision).
479
     *
480
     * @param \Carbon\CarbonInterface|\DateTimeInterface|string|null $date
481
     * @param bool                                                   $absolute Get the absolute of the difference
482
     *
483
     * @return float
484
     */
485
    public function floatDiffInSeconds($date = null, $absolute = true)
486
    {
487
        return (float) ($this->diffInMicroseconds($date, $absolute) / static::MICROSECONDS_PER_SECOND);
488
    }
489
 
490
    /**
491
     * Get the difference in minutes as float (microsecond-precision).
492
     *
493
     * @param \Carbon\CarbonInterface|\DateTimeInterface|string|null $date
494
     * @param bool                                                   $absolute Get the absolute of the difference
495
     *
496
     * @return float
497
     */
498
    public function floatDiffInMinutes($date = null, $absolute = true)
499
    {
500
        return $this->floatDiffInSeconds($date, $absolute) / static::SECONDS_PER_MINUTE;
501
    }
502
 
503
    /**
504
     * Get the difference in hours as float (microsecond-precision).
505
     *
506
     * @param \Carbon\CarbonInterface|\DateTimeInterface|string|null $date
507
     * @param bool                                                   $absolute Get the absolute of the difference
508
     *
509
     * @return float
510
     */
511
    public function floatDiffInHours($date = null, $absolute = true)
512
    {
513
        return $this->floatDiffInMinutes($date, $absolute) / static::MINUTES_PER_HOUR;
514
    }
515
 
516
    /**
517
     * Get the difference in days as float (microsecond-precision).
518
     *
519
     * @param \Carbon\CarbonInterface|\DateTimeInterface|string|null $date
520
     * @param bool                                                   $absolute Get the absolute of the difference
521
     *
522
     * @return float
523
     */
524
    public function floatDiffInDays($date = null, $absolute = true)
525
    {
526
        $hoursDiff = $this->floatDiffInHours($date, $absolute);
527
        $interval = $this->diff($date, $absolute);
528
 
529
        if ($interval->y === 0 && $interval->m === 0 && $interval->d === 0) {
530
            return $hoursDiff / static::HOURS_PER_DAY;
531
        }
532
 
533
        $daysDiff = $this->getIntervalDayDiff($interval);
534
 
535
        return $daysDiff + fmod($hoursDiff, static::HOURS_PER_DAY) / static::HOURS_PER_DAY;
536
    }
537
 
538
    /**
539
     * Get the difference in weeks as float (microsecond-precision).
540
     *
541
     * @param \Carbon\CarbonInterface|\DateTimeInterface|string|null $date
542
     * @param bool                                                   $absolute Get the absolute of the difference
543
     *
544
     * @return float
545
     */
546
    public function floatDiffInWeeks($date = null, $absolute = true)
547
    {
548
        return $this->floatDiffInDays($date, $absolute) / static::DAYS_PER_WEEK;
549
    }
550
 
551
    /**
552
     * Get the difference in months as float (microsecond-precision).
553
     *
554
     * @param \Carbon\CarbonInterface|\DateTimeInterface|string|null $date
555
     * @param bool                                                   $absolute Get the absolute of the difference
556
     *
557
     * @return float
558
     */
559
    public function floatDiffInMonths($date = null, $absolute = true)
560
    {
561
        $start = $this;
562
        $end = $this->resolveCarbon($date);
563
        $ascending = ($start <= $end);
564
        $sign = $absolute || $ascending ? 1 : -1;
565
        if (!$ascending) {
566
            [$start, $end] = [$end, $start];
567
        }
568
        $monthsDiff = $start->diffInMonths($end);
569
        /** @var Carbon|CarbonImmutable $floorEnd */
570
        $floorEnd = $start->avoidMutation()->addMonths($monthsDiff);
571
 
572
        if ($floorEnd >= $end) {
573
            return $sign * $monthsDiff;
574
        }
575
 
576
        /** @var Carbon|CarbonImmutable $startOfMonthAfterFloorEnd */
577
        $startOfMonthAfterFloorEnd = $floorEnd->avoidMutation()->addMonth()->startOfMonth();
578
 
579
        if ($startOfMonthAfterFloorEnd > $end) {
580
            return $sign * ($monthsDiff + $floorEnd->floatDiffInDays($end) / $floorEnd->daysInMonth);
581
        }
582
 
583
        return $sign * ($monthsDiff + $floorEnd->floatDiffInDays($startOfMonthAfterFloorEnd) / $floorEnd->daysInMonth + $startOfMonthAfterFloorEnd->floatDiffInDays($end) / $end->daysInMonth);
584
    }
585
 
586
    /**
587
     * Get the difference in year as float (microsecond-precision).
588
     *
589
     * @param \Carbon\CarbonInterface|\DateTimeInterface|string|null $date
590
     * @param bool                                                   $absolute Get the absolute of the difference
591
     *
592
     * @return float
593
     */
594
    public function floatDiffInYears($date = null, $absolute = true)
595
    {
596
        $start = $this;
597
        $end = $this->resolveCarbon($date);
598
        $ascending = ($start <= $end);
599
        $sign = $absolute || $ascending ? 1 : -1;
600
        if (!$ascending) {
601
            [$start, $end] = [$end, $start];
602
        }
603
        $yearsDiff = $start->diffInYears($end);
604
        /** @var Carbon|CarbonImmutable $floorEnd */
605
        $floorEnd = $start->avoidMutation()->addYears($yearsDiff);
606
 
607
        if ($floorEnd >= $end) {
608
            return $sign * $yearsDiff;
609
        }
610
 
611
        /** @var Carbon|CarbonImmutable $startOfYearAfterFloorEnd */
612
        $startOfYearAfterFloorEnd = $floorEnd->avoidMutation()->addYear()->startOfYear();
613
 
614
        if ($startOfYearAfterFloorEnd > $end) {
615
            return $sign * ($yearsDiff + $floorEnd->floatDiffInDays($end) / $floorEnd->daysInYear);
616
        }
617
 
618
        return $sign * ($yearsDiff + $floorEnd->floatDiffInDays($startOfYearAfterFloorEnd) / $floorEnd->daysInYear + $startOfYearAfterFloorEnd->floatDiffInDays($end) / $end->daysInYear);
619
    }
620
 
621
    /**
622
     * Get the difference in seconds as float (microsecond-precision) using timestamps.
623
     *
624
     * @param \Carbon\CarbonInterface|\DateTimeInterface|string|null $date
625
     * @param bool                                                   $absolute Get the absolute of the difference
626
     *
627
     * @return float
628
     */
629
    public function floatDiffInRealSeconds($date = null, $absolute = true)
630
    {
631
        return $this->diffInRealMicroseconds($date, $absolute) / static::MICROSECONDS_PER_SECOND;
632
    }
633
 
634
    /**
635
     * Get the difference in minutes as float (microsecond-precision) using timestamps.
636
     *
637
     * @param \Carbon\CarbonInterface|\DateTimeInterface|string|null $date
638
     * @param bool                                                   $absolute Get the absolute of the difference
639
     *
640
     * @return float
641
     */
642
    public function floatDiffInRealMinutes($date = null, $absolute = true)
643
    {
644
        return $this->floatDiffInRealSeconds($date, $absolute) / static::SECONDS_PER_MINUTE;
645
    }
646
 
647
    /**
648
     * Get the difference in hours as float (microsecond-precision) using timestamps.
649
     *
650
     * @param \Carbon\CarbonInterface|\DateTimeInterface|string|null $date
651
     * @param bool                                                   $absolute Get the absolute of the difference
652
     *
653
     * @return float
654
     */
655
    public function floatDiffInRealHours($date = null, $absolute = true)
656
    {
657
        return $this->floatDiffInRealMinutes($date, $absolute) / static::MINUTES_PER_HOUR;
658
    }
659
 
660
    /**
661
     * Get the difference in days as float (microsecond-precision).
662
     *
663
     * @param \Carbon\CarbonInterface|\DateTimeInterface|string|null $date
664
     * @param bool                                                   $absolute Get the absolute of the difference
665
     *
666
     * @return float
667
     */
668
    public function floatDiffInRealDays($date = null, $absolute = true)
669
    {
670
        $date = $this->resolveUTC($date);
671
        $utc = $this->avoidMutation()->utc();
672
        $hoursDiff = $utc->floatDiffInRealHours($date, $absolute);
673
 
674
        return ($hoursDiff < 0 ? -1 : 1) * $utc->diffInDays($date) + fmod($hoursDiff, static::HOURS_PER_DAY) / static::HOURS_PER_DAY;
675
    }
676
 
677
    /**
678
     * Get the difference in weeks as float (microsecond-precision).
679
     *
680
     * @param \Carbon\CarbonInterface|\DateTimeInterface|string|null $date
681
     * @param bool                                                   $absolute Get the absolute of the difference
682
     *
683
     * @return float
684
     */
685
    public function floatDiffInRealWeeks($date = null, $absolute = true)
686
    {
687
        return $this->floatDiffInRealDays($date, $absolute) / static::DAYS_PER_WEEK;
688
    }
689
 
690
    /**
691
     * Get the difference in months as float (microsecond-precision) using timestamps.
692
     *
693
     * @param \Carbon\CarbonInterface|\DateTimeInterface|string|null $date
694
     * @param bool                                                   $absolute Get the absolute of the difference
695
     *
696
     * @return float
697
     */
698
    public function floatDiffInRealMonths($date = null, $absolute = true)
699
    {
700
        $start = $this;
701
        $end = $this->resolveCarbon($date);
702
        $ascending = ($start <= $end);
703
        $sign = $absolute || $ascending ? 1 : -1;
704
        if (!$ascending) {
705
            [$start, $end] = [$end, $start];
706
        }
707
        $monthsDiff = $start->diffInMonths($end);
708
        /** @var Carbon|CarbonImmutable $floorEnd */
709
        $floorEnd = $start->avoidMutation()->addMonths($monthsDiff);
710
 
711
        if ($floorEnd >= $end) {
712
            return $sign * $monthsDiff;
713
        }
714
 
715
        /** @var Carbon|CarbonImmutable $startOfMonthAfterFloorEnd */
716
        $startOfMonthAfterFloorEnd = $floorEnd->avoidMutation()->addMonth()->startOfMonth();
717
 
718
        if ($startOfMonthAfterFloorEnd > $end) {
719
            return $sign * ($monthsDiff + $floorEnd->floatDiffInRealDays($end) / $floorEnd->daysInMonth);
720
        }
721
 
722
        return $sign * ($monthsDiff + $floorEnd->floatDiffInRealDays($startOfMonthAfterFloorEnd) / $floorEnd->daysInMonth + $startOfMonthAfterFloorEnd->floatDiffInRealDays($end) / $end->daysInMonth);
723
    }
724
 
725
    /**
726
     * Get the difference in year as float (microsecond-precision) using timestamps.
727
     *
728
     * @param \Carbon\CarbonInterface|\DateTimeInterface|string|null $date
729
     * @param bool                                                   $absolute Get the absolute of the difference
730
     *
731
     * @return float
732
     */
733
    public function floatDiffInRealYears($date = null, $absolute = true)
734
    {
735
        $start = $this;
736
        $end = $this->resolveCarbon($date);
737
        $ascending = ($start <= $end);
738
        $sign = $absolute || $ascending ? 1 : -1;
739
        if (!$ascending) {
740
            [$start, $end] = [$end, $start];
741
        }
742
        $yearsDiff = $start->diffInYears($end);
743
        /** @var Carbon|CarbonImmutable $floorEnd */
744
        $floorEnd = $start->avoidMutation()->addYears($yearsDiff);
745
 
746
        if ($floorEnd >= $end) {
747
            return $sign * $yearsDiff;
748
        }
749
 
750
        /** @var Carbon|CarbonImmutable $startOfYearAfterFloorEnd */
751
        $startOfYearAfterFloorEnd = $floorEnd->avoidMutation()->addYear()->startOfYear();
752
 
753
        if ($startOfYearAfterFloorEnd > $end) {
754
            return $sign * ($yearsDiff + $floorEnd->floatDiffInRealDays($end) / $floorEnd->daysInYear);
755
        }
756
 
757
        return $sign * ($yearsDiff + $floorEnd->floatDiffInRealDays($startOfYearAfterFloorEnd) / $floorEnd->daysInYear + $startOfYearAfterFloorEnd->floatDiffInRealDays($end) / $end->daysInYear);
758
    }
759
 
760
    /**
761
     * The number of seconds since midnight.
762
     *
763
     * @return int
764
     */
765
    public function secondsSinceMidnight()
766
    {
767
        return $this->diffInSeconds($this->avoidMutation()->startOfDay());
768
    }
769
 
770
    /**
771
     * The number of seconds until 23:59:59.
772
     *
773
     * @return int
774
     */
775
    public function secondsUntilEndOfDay()
776
    {
777
        return $this->diffInSeconds($this->avoidMutation()->endOfDay());
778
    }
779
 
780
    /**
781
     * Get the difference in a human readable format in the current locale from current instance to an other
782
     * instance given (or now if null given).
783
     *
784
     * @example
785
     * ```
786
     * echo Carbon::tomorrow()->diffForHumans() . "\n";
787
     * echo Carbon::tomorrow()->diffForHumans(['parts' => 2]) . "\n";
788
     * echo Carbon::tomorrow()->diffForHumans(['parts' => 3, 'join' => true]) . "\n";
789
     * echo Carbon::tomorrow()->diffForHumans(Carbon::yesterday()) . "\n";
790
     * echo Carbon::tomorrow()->diffForHumans(Carbon::yesterday(), ['short' => true]) . "\n";
791
     * ```
792
     *
793
     * @param Carbon|\DateTimeInterface|string|array|null $other   if array passed, will be used as parameters array, see $syntax below;
794
     *                                                             if null passed, now will be used as comparison reference;
795
     *                                                             if any other type, it will be converted to date and used as reference.
796
     * @param int|array                                   $syntax  if array passed, parameters will be extracted from it, the array may contains:
797
     *                                                             - 'syntax' entry (see below)
798
     *                                                             - 'short' entry (see below)
799
     *                                                             - 'parts' entry (see below)
800
     *                                                             - 'options' entry (see below)
801
     *                                                             - 'skip' entry, list of units to skip (array of strings or a single string,
802
     *                                                             ` it can be the unit name (singular or plural) or its shortcut
803
     *                                                             ` (y, m, w, d, h, min, s, ms, µs).
804
     *                                                             - 'aUnit' entry, prefer "an hour" over "1 hour" if true
805
     *                                                             - 'join' entry determines how to join multiple parts of the string
806
     *                                                             `  - if $join is a string, it's used as a joiner glue
807
     *                                                             `  - if $join is a callable/closure, it get the list of string and should return a string
808
     *                                                             `  - if $join is an array, the first item will be the default glue, and the second item
809
     *                                                             `    will be used instead of the glue for the last item
810
     *                                                             `  - if $join is true, it will be guessed from the locale ('list' translation file entry)
811
     *                                                             `  - if $join is missing, a space will be used as glue
812
     *                                                             - 'other' entry (see above)
813
     *                                                             - 'minimumUnit' entry determines the smallest unit of time to display can be long or
814
     *                                                             `  short form of the units, e.g. 'hour' or 'h' (default value: s)
815
     *                                                             if int passed, it add modifiers:
816
     *                                                             Possible values:
817
     *                                                             - CarbonInterface::DIFF_ABSOLUTE          no modifiers
818
     *                                                             - CarbonInterface::DIFF_RELATIVE_TO_NOW   add ago/from now modifier
819
     *                                                             - CarbonInterface::DIFF_RELATIVE_TO_OTHER add before/after modifier
820
     *                                                             Default value: CarbonInterface::DIFF_ABSOLUTE
821
     * @param bool                                        $short   displays short format of time units
822
     * @param int                                         $parts   maximum number of parts to display (default value: 1: single unit)
823
     * @param int                                         $options human diff options
824
     *
825
     * @return string
826
     */
827
    public function diffForHumans($other = null, $syntax = null, $short = false, $parts = 1, $options = null)
828
    {
829
        /* @var CarbonInterface $this */
830
        if (\is_array($other)) {
831
            $other['syntax'] = \array_key_exists('syntax', $other) ? $other['syntax'] : $syntax;
832
            $syntax = $other;
833
            $other = $syntax['other'] ?? null;
834
        }
835
 
836
        $intSyntax = &$syntax;
837
        if (\is_array($syntax)) {
838
            $syntax['syntax'] = $syntax['syntax'] ?? null;
839
            $intSyntax = &$syntax['syntax'];
840
        }
841
        $intSyntax = (int) ($intSyntax ?? static::DIFF_RELATIVE_AUTO);
842
        $intSyntax = $intSyntax === static::DIFF_RELATIVE_AUTO && $other === null ? static::DIFF_RELATIVE_TO_NOW : $intSyntax;
843
 
844
        $parts = min(7, max(1, (int) $parts));
845
        $skip = \is_array($syntax) ? ($syntax['skip'] ?? []) : [];
846
 
847
        return $this->diffAsCarbonInterval($other, false, (array) $skip)
848
            ->setLocalTranslator($this->getLocalTranslator())
849
            ->forHumans($syntax, (bool) $short, $parts, $options ?? $this->localHumanDiffOptions ?? static::getHumanDiffOptions());
850
    }
851
 
852
    /**
853
     * @alias diffForHumans
854
     *
855
     * Get the difference in a human readable format in the current locale from current instance to an other
856
     * instance given (or now if null given).
857
     *
858
     * @param Carbon|\DateTimeInterface|string|array|null $other   if array passed, will be used as parameters array, see $syntax below;
859
     *                                                             if null passed, now will be used as comparison reference;
860
     *                                                             if any other type, it will be converted to date and used as reference.
861
     * @param int|array                                   $syntax  if array passed, parameters will be extracted from it, the array may contains:
862
     *                                                             - 'syntax' entry (see below)
863
     *                                                             - 'short' entry (see below)
864
     *                                                             - 'parts' entry (see below)
865
     *                                                             - 'options' entry (see below)
866
     *                                                             - 'join' entry determines how to join multiple parts of the string
867
     *                                                             `  - if $join is a string, it's used as a joiner glue
868
     *                                                             `  - if $join is a callable/closure, it get the list of string and should return a string
869
     *                                                             `  - if $join is an array, the first item will be the default glue, and the second item
870
     *                                                             `    will be used instead of the glue for the last item
871
     *                                                             `  - if $join is true, it will be guessed from the locale ('list' translation file entry)
872
     *                                                             `  - if $join is missing, a space will be used as glue
873
     *                                                             - 'other' entry (see above)
874
     *                                                             if int passed, it add modifiers:
875
     *                                                             Possible values:
876
     *                                                             - CarbonInterface::DIFF_ABSOLUTE          no modifiers
877
     *                                                             - CarbonInterface::DIFF_RELATIVE_TO_NOW   add ago/from now modifier
878
     *                                                             - CarbonInterface::DIFF_RELATIVE_TO_OTHER add before/after modifier
879
     *                                                             Default value: CarbonInterface::DIFF_ABSOLUTE
880
     * @param bool                                        $short   displays short format of time units
881
     * @param int                                         $parts   maximum number of parts to display (default value: 1: single unit)
882
     * @param int                                         $options human diff options
883
     *
884
     * @return string
885
     */
886
    public function from($other = null, $syntax = null, $short = false, $parts = 1, $options = null)
887
    {
888
        return $this->diffForHumans($other, $syntax, $short, $parts, $options);
889
    }
890
 
891
    /**
892
     * @alias diffForHumans
893
     *
894
     * Get the difference in a human readable format in the current locale from current instance to an other
895
     * instance given (or now if null given).
896
     */
897
    public function since($other = null, $syntax = null, $short = false, $parts = 1, $options = null)
898
    {
899
        return $this->diffForHumans($other, $syntax, $short, $parts, $options);
900
    }
901
 
902
    /**
903
     * Get the difference in a human readable format in the current locale from an other
904
     * instance given (or now if null given) to current instance.
905
     *
906
     * When comparing a value in the past to default now:
907
     * 1 hour from now
908
     * 5 months from now
909
     *
910
     * When comparing a value in the future to default now:
911
     * 1 hour ago
912
     * 5 months ago
913
     *
914
     * When comparing a value in the past to another value:
915
     * 1 hour after
916
     * 5 months after
917
     *
918
     * When comparing a value in the future to another value:
919
     * 1 hour before
920
     * 5 months before
921
     *
922
     * @param Carbon|\DateTimeInterface|string|array|null $other   if array passed, will be used as parameters array, see $syntax below;
923
     *                                                             if null passed, now will be used as comparison reference;
924
     *                                                             if any other type, it will be converted to date and used as reference.
925
     * @param int|array                                   $syntax  if array passed, parameters will be extracted from it, the array may contains:
926
     *                                                             - 'syntax' entry (see below)
927
     *                                                             - 'short' entry (see below)
928
     *                                                             - 'parts' entry (see below)
929
     *                                                             - 'options' entry (see below)
930
     *                                                             - 'join' entry determines how to join multiple parts of the string
931
     *                                                             `  - if $join is a string, it's used as a joiner glue
932
     *                                                             `  - if $join is a callable/closure, it get the list of string and should return a string
933
     *                                                             `  - if $join is an array, the first item will be the default glue, and the second item
934
     *                                                             `    will be used instead of the glue for the last item
935
     *                                                             `  - if $join is true, it will be guessed from the locale ('list' translation file entry)
936
     *                                                             `  - if $join is missing, a space will be used as glue
937
     *                                                             - 'other' entry (see above)
938
     *                                                             if int passed, it add modifiers:
939
     *                                                             Possible values:
940
     *                                                             - CarbonInterface::DIFF_ABSOLUTE          no modifiers
941
     *                                                             - CarbonInterface::DIFF_RELATIVE_TO_NOW   add ago/from now modifier
942
     *                                                             - CarbonInterface::DIFF_RELATIVE_TO_OTHER add before/after modifier
943
     *                                                             Default value: CarbonInterface::DIFF_ABSOLUTE
944
     * @param bool                                        $short   displays short format of time units
945
     * @param int                                         $parts   maximum number of parts to display (default value: 1: single unit)
946
     * @param int                                         $options human diff options
947
     *
948
     * @return string
949
     */
950
    public function to($other = null, $syntax = null, $short = false, $parts = 1, $options = null)
951
    {
952
        if (!$syntax && !$other) {
953
            $syntax = CarbonInterface::DIFF_RELATIVE_TO_NOW;
954
        }
955
 
956
        return $this->resolveCarbon($other)->diffForHumans($this, $syntax, $short, $parts, $options);
957
    }
958
 
959
    /**
960
     * @alias to
961
     *
962
     * Get the difference in a human readable format in the current locale from an other
963
     * instance given (or now if null given) to current instance.
964
     *
965
     * @param Carbon|\DateTimeInterface|string|array|null $other   if array passed, will be used as parameters array, see $syntax below;
966
     *                                                             if null passed, now will be used as comparison reference;
967
     *                                                             if any other type, it will be converted to date and used as reference.
968
     * @param int|array                                   $syntax  if array passed, parameters will be extracted from it, the array may contains:
969
     *                                                             - 'syntax' entry (see below)
970
     *                                                             - 'short' entry (see below)
971
     *                                                             - 'parts' entry (see below)
972
     *                                                             - 'options' entry (see below)
973
     *                                                             - 'join' entry determines how to join multiple parts of the string
974
     *                                                             `  - if $join is a string, it's used as a joiner glue
975
     *                                                             `  - if $join is a callable/closure, it get the list of string and should return a string
976
     *                                                             `  - if $join is an array, the first item will be the default glue, and the second item
977
     *                                                             `    will be used instead of the glue for the last item
978
     *                                                             `  - if $join is true, it will be guessed from the locale ('list' translation file entry)
979
     *                                                             `  - if $join is missing, a space will be used as glue
980
     *                                                             - 'other' entry (see above)
981
     *                                                             if int passed, it add modifiers:
982
     *                                                             Possible values:
983
     *                                                             - CarbonInterface::DIFF_ABSOLUTE          no modifiers
984
     *                                                             - CarbonInterface::DIFF_RELATIVE_TO_NOW   add ago/from now modifier
985
     *                                                             - CarbonInterface::DIFF_RELATIVE_TO_OTHER add before/after modifier
986
     *                                                             Default value: CarbonInterface::DIFF_ABSOLUTE
987
     * @param bool                                        $short   displays short format of time units
988
     * @param int                                         $parts   maximum number of parts to display (default value: 1: single unit)
989
     * @param int                                         $options human diff options
990
     *
991
     * @return string
992
     */
993
    public function until($other = null, $syntax = null, $short = false, $parts = 1, $options = null)
994
    {
995
        return $this->to($other, $syntax, $short, $parts, $options);
996
    }
997
 
998
    /**
999
     * Get the difference in a human readable format in the current locale from current
1000
     * instance to now.
1001
     *
1002
     * @param int|array $syntax  if array passed, parameters will be extracted from it, the array may contains:
1003
     *                           - 'syntax' entry (see below)
1004
     *                           - 'short' entry (see below)
1005
     *                           - 'parts' entry (see below)
1006
     *                           - 'options' entry (see below)
1007
     *                           - 'join' entry determines how to join multiple parts of the string
1008
     *                           `  - if $join is a string, it's used as a joiner glue
1009
     *                           `  - if $join is a callable/closure, it get the list of string and should return a string
1010
     *                           `  - if $join is an array, the first item will be the default glue, and the second item
1011
     *                           `    will be used instead of the glue for the last item
1012
     *                           `  - if $join is true, it will be guessed from the locale ('list' translation file entry)
1013
     *                           `  - if $join is missing, a space will be used as glue
1014
     *                           if int passed, it add modifiers:
1015
     *                           Possible values:
1016
     *                           - CarbonInterface::DIFF_ABSOLUTE          no modifiers
1017
     *                           - CarbonInterface::DIFF_RELATIVE_TO_NOW   add ago/from now modifier
1018
     *                           - CarbonInterface::DIFF_RELATIVE_TO_OTHER add before/after modifier
1019
     *                           Default value: CarbonInterface::DIFF_ABSOLUTE
1020
     * @param bool      $short   displays short format of time units
1021
     * @param int       $parts   maximum number of parts to display (default value: 1: single unit)
1022
     * @param int       $options human diff options
1023
     *
1024
     * @return string
1025
     */
1026
    public function fromNow($syntax = null, $short = false, $parts = 1, $options = null)
1027
    {
1028
        $other = null;
1029
 
1030
        if ($syntax instanceof DateTimeInterface) {
1031
            [$other, $syntax, $short, $parts, $options] = array_pad(\func_get_args(), 5, null);
1032
        }
1033
 
1034
        return $this->from($other, $syntax, $short, $parts, $options);
1035
    }
1036
 
1037
    /**
1038
     * Get the difference in a human readable format in the current locale from an other
1039
     * instance given to now
1040
     *
1041
     * @param int|array $syntax  if array passed, parameters will be extracted from it, the array may contains:
1042
     *                           - 'syntax' entry (see below)
1043
     *                           - 'short' entry (see below)
1044
     *                           - 'parts' entry (see below)
1045
     *                           - 'options' entry (see below)
1046
     *                           - 'join' entry determines how to join multiple parts of the string
1047
     *                           `  - if $join is a string, it's used as a joiner glue
1048
     *                           `  - if $join is a callable/closure, it get the list of string and should return a string
1049
     *                           `  - if $join is an array, the first item will be the default glue, and the second item
1050
     *                           `    will be used instead of the glue for the last item
1051
     *                           `  - if $join is true, it will be guessed from the locale ('list' translation file entry)
1052
     *                           `  - if $join is missing, a space will be used as glue
1053
     *                           if int passed, it add modifiers:
1054
     *                           Possible values:
1055
     *                           - CarbonInterface::DIFF_ABSOLUTE          no modifiers
1056
     *                           - CarbonInterface::DIFF_RELATIVE_TO_NOW   add ago/from now modifier
1057
     *                           - CarbonInterface::DIFF_RELATIVE_TO_OTHER add before/after modifier
1058
     *                           Default value: CarbonInterface::DIFF_ABSOLUTE
1059
     * @param bool      $short   displays short format of time units
1060
     * @param int       $parts   maximum number of parts to display (default value: 1: single part)
1061
     * @param int       $options human diff options
1062
     *
1063
     * @return string
1064
     */
1065
    public function toNow($syntax = null, $short = false, $parts = 1, $options = null)
1066
    {
1067
        return $this->to(null, $syntax, $short, $parts, $options);
1068
    }
1069
 
1070
    /**
1071
     * Get the difference in a human readable format in the current locale from an other
1072
     * instance given to now
1073
     *
1074
     * @param int|array $syntax  if array passed, parameters will be extracted from it, the array may contains:
1075
     *                           - 'syntax' entry (see below)
1076
     *                           - 'short' entry (see below)
1077
     *                           - 'parts' entry (see below)
1078
     *                           - 'options' entry (see below)
1079
     *                           - 'join' entry determines how to join multiple parts of the string
1080
     *                           `  - if $join is a string, it's used as a joiner glue
1081
     *                           `  - if $join is a callable/closure, it get the list of string and should return a string
1082
     *                           `  - if $join is an array, the first item will be the default glue, and the second item
1083
     *                           `    will be used instead of the glue for the last item
1084
     *                           `  - if $join is true, it will be guessed from the locale ('list' translation file entry)
1085
     *                           `  - if $join is missing, a space will be used as glue
1086
     *                           if int passed, it add modifiers:
1087
     *                           Possible values:
1088
     *                           - CarbonInterface::DIFF_ABSOLUTE          no modifiers
1089
     *                           - CarbonInterface::DIFF_RELATIVE_TO_NOW   add ago/from now modifier
1090
     *                           - CarbonInterface::DIFF_RELATIVE_TO_OTHER add before/after modifier
1091
     *                           Default value: CarbonInterface::DIFF_ABSOLUTE
1092
     * @param bool      $short   displays short format of time units
1093
     * @param int       $parts   maximum number of parts to display (default value: 1: single part)
1094
     * @param int       $options human diff options
1095
     *
1096
     * @return string
1097
     */
1098
    public function ago($syntax = null, $short = false, $parts = 1, $options = null)
1099
    {
1100
        $other = null;
1101
 
1102
        if ($syntax instanceof DateTimeInterface) {
1103
            [$other, $syntax, $short, $parts, $options] = array_pad(\func_get_args(), 5, null);
1104
        }
1105
 
1106
        return $this->from($other, $syntax, $short, $parts, $options);
1107
    }
1108
 
1109
    /**
1110
     * Get the difference in a human readable format in the current locale from current instance to an other
1111
     * instance given (or now if null given).
1112
     *
1113
     * @return string
1114
     */
1115
    public function timespan($other = null, $timezone = null)
1116
    {
1117
        if (!$other instanceof DateTimeInterface) {
1118
            $other = static::parse($other, $timezone);
1119
        }
1120
 
1121
        return $this->diffForHumans($other, [
1122
            'join' => ', ',
1123
            'syntax' => CarbonInterface::DIFF_ABSOLUTE,
1124
            'options' => CarbonInterface::NO_ZERO_DIFF,
1125
            'parts' => -1,
1126
        ]);
1127
    }
1128
 
1129
    /**
1130
     * Returns either day of week + time (e.g. "Last Friday at 3:30 PM") if reference time is within 7 days,
1131
     * or a calendar date (e.g. "10/29/2017") otherwise.
1132
     *
1133
     * Language, date and time formats will change according to the current locale.
1134
     *
1135
     * @param Carbon|\DateTimeInterface|string|null $referenceTime
1136
     * @param array                                 $formats
1137
     *
1138
     * @return string
1139
     */
1140
    public function calendar($referenceTime = null, array $formats = [])
1141
    {
1142
        /** @var CarbonInterface $current */
1143
        $current = $this->avoidMutation()->startOfDay();
1144
        /** @var CarbonInterface $other */
1145
        $other = $this->resolveCarbon($referenceTime)->avoidMutation()->setTimezone($this->getTimezone())->startOfDay();
1146
        $diff = $other->diffInDays($current, false);
1147
        $format = $diff < -6 ? 'sameElse' : (
1148
            $diff < -1 ? 'lastWeek' : (
1149
                $diff < 0 ? 'lastDay' : (
1150
                    $diff < 1 ? 'sameDay' : (
1151
                        $diff < 2 ? 'nextDay' : (
1152
                            $diff < 7 ? 'nextWeek' : 'sameElse'
1153
                        )
1154
                    )
1155
                )
1156
            )
1157
        );
1158
        $format = array_merge($this->getCalendarFormats(), $formats)[$format];
1159
        if ($format instanceof Closure) {
1160
            $format = $format($current, $other) ?? '';
1161
        }
1162
 
1163
        return $this->isoFormat((string) $format);
1164
    }
1165
 
1166
    private function getIntervalDayDiff(DateInterval $interval): int
1167
    {
1168
        $daysDiff = (int) $interval->format('%a');
1169
        $sign = $interval->format('%r') === '-' ? -1 : 1;
1170
 
1171
        if (\is_int($interval->days) &&
1172
            $interval->y === 0 &&
1173
            $interval->m === 0 &&
1174
            version_compare(PHP_VERSION, '8.1.0-dev', '<') &&
1175
            abs($interval->d - $daysDiff) === 1
1176
        ) {
1177
            $daysDiff = abs($interval->d); // @codeCoverageIgnore
1178
        }
1179
 
1180
        return $daysDiff * $sign;
1181
    }
1182
}