blob: 82d7c32649bdad656dca2838cf876ed2209ac787 [file] [log] [blame]
Matthias Andreas Benkard7b2a3a12021-08-16 10:57:25 +02001<?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 */
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +010011
Matthias Andreas Benkard7b2a3a12021-08-16 10:57:25 +020012namespace Carbon\Traits;
13
14use Carbon\Carbon;
15use Carbon\CarbonImmutable;
16use Carbon\CarbonInterface;
17use Closure;
18use DateTimeImmutable;
19use DateTimeInterface;
20
21trait IntervalStep
22{
23 /**
24 * Step to apply instead of a fixed interval to get the new date.
25 *
26 * @var Closure|null
27 */
28 protected $step;
29
30 /**
31 * Get the dynamic step in use.
32 *
33 * @return Closure
34 */
35 public function getStep(): ?Closure
36 {
37 return $this->step;
38 }
39
40 /**
41 * Set a step to apply instead of a fixed interval to get the new date.
42 *
43 * Or pass null to switch to fixed interval.
44 *
45 * @param Closure|null $step
46 */
47 public function setStep(?Closure $step): void
48 {
49 $this->step = $step;
50 }
51
52 /**
53 * Take a date and apply either the step if set, or the current interval else.
54 *
55 * The interval/step is applied negatively (typically subtraction instead of addition) if $negated is true.
56 *
57 * @param DateTimeInterface $dateTime
58 * @param bool $negated
59 *
60 * @return CarbonInterface
61 */
62 public function convertDate(DateTimeInterface $dateTime, bool $negated = false): CarbonInterface
63 {
64 /** @var CarbonInterface $carbonDate */
65 $carbonDate = $dateTime instanceof CarbonInterface ? $dateTime : $this->resolveCarbon($dateTime);
66
67 if ($this->step) {
68 return $carbonDate->setDateTimeFrom(($this->step)($carbonDate->avoidMutation(), $negated));
69 }
70
71 if ($negated) {
72 return $carbonDate->rawSub($this);
73 }
74
75 return $carbonDate->rawAdd($this);
76 }
77
78 /**
79 * Convert DateTimeImmutable instance to CarbonImmutable instance and DateTime instance to Carbon instance.
80 *
81 * @param DateTimeInterface $dateTime
82 *
83 * @return Carbon|CarbonImmutable
84 */
85 private function resolveCarbon(DateTimeInterface $dateTime)
86 {
87 if ($dateTime instanceof DateTimeImmutable) {
88 return CarbonImmutable::instance($dateTime);
89 }
90
91 return Carbon::instance($dateTime);
92 }
93}