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
12namespace Carbon\Traits;
13
14use BadMethodCallException;
15use Carbon\Carbon;
16use Carbon\CarbonInterface;
17use Carbon\CarbonPeriod;
18use Carbon\CarbonTimeZone;
19use Carbon\Exceptions\BadComparisonUnitException;
20use Carbon\Exceptions\ImmutableException;
21use Carbon\Exceptions\InvalidTimeZoneException;
22use Carbon\Exceptions\InvalidTypeException;
23use Carbon\Exceptions\UnknownGetterException;
24use Carbon\Exceptions\UnknownMethodException;
25use Carbon\Exceptions\UnknownSetterException;
26use Carbon\Exceptions\UnknownUnitException;
27use Closure;
28use DateInterval;
29use DatePeriod;
30use DateTime;
31use DateTimeImmutable;
32use DateTimeInterface;
33use DateTimeZone;
34use InvalidArgumentException;
35use ReflectionException;
36use ReturnTypeWillChange;
37use Throwable;
38
39/**
40 * A simple API extension for DateTime.
41 *
42 * <autodoc generated by `composer phpdoc`>
43 *
44 * @property      int              $year
45 * @property      int              $yearIso
46 * @property      int              $month
47 * @property      int              $day
48 * @property      int              $hour
49 * @property      int              $minute
50 * @property      int              $second
51 * @property      int              $micro
52 * @property      int              $microsecond
53 * @property      int|float|string $timestamp                                                                         seconds since the Unix Epoch
54 * @property      string           $englishDayOfWeek                                                                  the day of week in English
55 * @property      string           $shortEnglishDayOfWeek                                                             the abbreviated day of week in English
56 * @property      string           $englishMonth                                                                      the month in English
57 * @property      string           $shortEnglishMonth                                                                 the abbreviated month in English
58 * @property      string           $localeDayOfWeek                                                                   the day of week in current locale LC_TIME
59 * @property      string           $shortLocaleDayOfWeek                                                              the abbreviated day of week in current locale LC_TIME
60 * @property      string           $localeMonth                                                                       the month in current locale LC_TIME
61 * @property      string           $shortLocaleMonth                                                                  the abbreviated month in current locale LC_TIME
62 * @property      int              $milliseconds
63 * @property      int              $millisecond
64 * @property      int              $milli
65 * @property      int              $week                                                                              1 through 53
66 * @property      int              $isoWeek                                                                           1 through 53
67 * @property      int              $weekYear                                                                          year according to week format
68 * @property      int              $isoWeekYear                                                                       year according to ISO week format
69 * @property      int              $dayOfYear                                                                         1 through 366
70 * @property      int              $age                                                                               does a diffInYears() with default parameters
71 * @property      int              $offset                                                                            the timezone offset in seconds from UTC
72 * @property      int              $offsetMinutes                                                                     the timezone offset in minutes from UTC
73 * @property      int              $offsetHours                                                                       the timezone offset in hours from UTC
74 * @property      CarbonTimeZone   $timezone                                                                          the current timezone
75 * @property      CarbonTimeZone   $tz                                                                                alias of $timezone
76 * @property-read int              $dayOfWeek                                                                         0 (for Sunday) through 6 (for Saturday)
77 * @property-read int              $dayOfWeekIso                                                                      1 (for Monday) through 7 (for Sunday)
78 * @property-read int              $weekOfYear                                                                        ISO-8601 week number of year, weeks starting on Monday
79 * @property-read int              $daysInMonth                                                                       number of days in the given month
80 * @property-read string           $latinMeridiem                                                                     "am"/"pm" (Ante meridiem or Post meridiem latin lowercase mark)
81 * @property-read string           $latinUpperMeridiem                                                                "AM"/"PM" (Ante meridiem or Post meridiem latin uppercase mark)
82 * @property-read string           $timezoneAbbreviatedName                                                           the current timezone abbreviated name
83 * @property-read string           $tzAbbrName                                                                        alias of $timezoneAbbreviatedName
84 * @property-read string           $dayName                                                                           long name of weekday translated according to Carbon locale, in english if no translation available for current language
85 * @property-read string           $shortDayName                                                                      short name of weekday translated according to Carbon locale, in english if no translation available for current language
86 * @property-read string           $minDayName                                                                        very short name of weekday translated according to Carbon locale, in english if no translation available for current language
87 * @property-read string           $monthName                                                                         long name of month translated according to Carbon locale, in english if no translation available for current language
88 * @property-read string           $shortMonthName                                                                    short name of month translated according to Carbon locale, in english if no translation available for current language
89 * @property-read string           $meridiem                                                                          lowercase meridiem mark translated according to Carbon locale, in latin if no translation available for current language
90 * @property-read string           $upperMeridiem                                                                     uppercase meridiem mark translated according to Carbon locale, in latin if no translation available for current language
91 * @property-read int              $noZeroHour                                                                        current hour from 1 to 24
92 * @property-read int              $weeksInYear                                                                       51 through 53
93 * @property-read int              $isoWeeksInYear                                                                    51 through 53
94 * @property-read int              $weekOfMonth                                                                       1 through 5
95 * @property-read int              $weekNumberInMonth                                                                 1 through 5
96 * @property-read int              $firstWeekDay                                                                      0 through 6
97 * @property-read int              $lastWeekDay                                                                       0 through 6
98 * @property-read int              $daysInYear                                                                        365 or 366
99 * @property-read int              $quarter                                                                           the quarter of this instance, 1 - 4
100 * @property-read int              $decade                                                                            the decade of this instance
101 * @property-read int              $century                                                                           the century of this instance
102 * @property-read int              $millennium                                                                        the millennium of this instance
103 * @property-read bool             $dst                                                                               daylight savings time indicator, true if DST, false otherwise
104 * @property-read bool             $local                                                                             checks if the timezone is local, true if local, false otherwise
105 * @property-read bool             $utc                                                                               checks if the timezone is UTC, true if UTC, false otherwise
106 * @property-read string           $timezoneName                                                                      the current timezone name
107 * @property-read string           $tzName                                                                            alias of $timezoneName
108 * @property-read string           $locale                                                                            locale of the current instance
109 *
110 * @method        bool             isUtc()                                                                            Check if the current instance has UTC timezone. (Both isUtc and isUTC cases are valid.)
111 * @method        bool             isLocal()                                                                          Check if the current instance has non-UTC timezone.
112 * @method        bool             isValid()                                                                          Check if the current instance is a valid date.
113 * @method        bool             isDST()                                                                            Check if the current instance is in a daylight saving time.
114 * @method        bool             isSunday()                                                                         Checks if the instance day is sunday.
115 * @method        bool             isMonday()                                                                         Checks if the instance day is monday.
116 * @method        bool             isTuesday()                                                                        Checks if the instance day is tuesday.
117 * @method        bool             isWednesday()                                                                      Checks if the instance day is wednesday.
118 * @method        bool             isThursday()                                                                       Checks if the instance day is thursday.
119 * @method        bool             isFriday()                                                                         Checks if the instance day is friday.
120 * @method        bool             isSaturday()                                                                       Checks if the instance day is saturday.
121 * @method        bool             isSameYear(Carbon|DateTimeInterface|string|null $date = null)                      Checks if the given date is in the same year as the instance. If null passed, compare to now (with the same timezone).
122 * @method        bool             isCurrentYear()                                                                    Checks if the instance is in the same year as the current moment.
123 * @method        bool             isNextYear()                                                                       Checks if the instance is in the same year as the current moment next year.
124 * @method        bool             isLastYear()                                                                       Checks if the instance is in the same year as the current moment last year.
125 * @method        bool             isSameWeek(Carbon|DateTimeInterface|string|null $date = null)                      Checks if the given date is in the same week as the instance. If null passed, compare to now (with the same timezone).
126 * @method        bool             isCurrentWeek()                                                                    Checks if the instance is in the same week as the current moment.
127 * @method        bool             isNextWeek()                                                                       Checks if the instance is in the same week as the current moment next week.
128 * @method        bool             isLastWeek()                                                                       Checks if the instance is in the same week as the current moment last week.
129 * @method        bool             isSameDay(Carbon|DateTimeInterface|string|null $date = null)                       Checks if the given date is in the same day as the instance. If null passed, compare to now (with the same timezone).
130 * @method        bool             isCurrentDay()                                                                     Checks if the instance is in the same day as the current moment.
131 * @method        bool             isNextDay()                                                                        Checks if the instance is in the same day as the current moment next day.
132 * @method        bool             isLastDay()                                                                        Checks if the instance is in the same day as the current moment last day.
133 * @method        bool             isSameHour(Carbon|DateTimeInterface|string|null $date = null)                      Checks if the given date is in the same hour as the instance. If null passed, compare to now (with the same timezone).
134 * @method        bool             isCurrentHour()                                                                    Checks if the instance is in the same hour as the current moment.
135 * @method        bool             isNextHour()                                                                       Checks if the instance is in the same hour as the current moment next hour.
136 * @method        bool             isLastHour()                                                                       Checks if the instance is in the same hour as the current moment last hour.
137 * @method        bool             isSameMinute(Carbon|DateTimeInterface|string|null $date = null)                    Checks if the given date is in the same minute as the instance. If null passed, compare to now (with the same timezone).
138 * @method        bool             isCurrentMinute()                                                                  Checks if the instance is in the same minute as the current moment.
139 * @method        bool             isNextMinute()                                                                     Checks if the instance is in the same minute as the current moment next minute.
140 * @method        bool             isLastMinute()                                                                     Checks if the instance is in the same minute as the current moment last minute.
141 * @method        bool             isSameSecond(Carbon|DateTimeInterface|string|null $date = null)                    Checks if the given date is in the same second as the instance. If null passed, compare to now (with the same timezone).
142 * @method        bool             isCurrentSecond()                                                                  Checks if the instance is in the same second as the current moment.
143 * @method        bool             isNextSecond()                                                                     Checks if the instance is in the same second as the current moment next second.
144 * @method        bool             isLastSecond()                                                                     Checks if the instance is in the same second as the current moment last second.
145 * @method        bool             isSameMicro(Carbon|DateTimeInterface|string|null $date = null)                     Checks if the given date is in the same microsecond as the instance. If null passed, compare to now (with the same timezone).
146 * @method        bool             isCurrentMicro()                                                                   Checks if the instance is in the same microsecond as the current moment.
147 * @method        bool             isNextMicro()                                                                      Checks if the instance is in the same microsecond as the current moment next microsecond.
148 * @method        bool             isLastMicro()                                                                      Checks if the instance is in the same microsecond as the current moment last microsecond.
149 * @method        bool             isSameMicrosecond(Carbon|DateTimeInterface|string|null $date = null)               Checks if the given date is in the same microsecond as the instance. If null passed, compare to now (with the same timezone).
150 * @method        bool             isCurrentMicrosecond()                                                             Checks if the instance is in the same microsecond as the current moment.
151 * @method        bool             isNextMicrosecond()                                                                Checks if the instance is in the same microsecond as the current moment next microsecond.
152 * @method        bool             isLastMicrosecond()                                                                Checks if the instance is in the same microsecond as the current moment last microsecond.
153 * @method        bool             isCurrentMonth()                                                                   Checks if the instance is in the same month as the current moment.
154 * @method        bool             isNextMonth()                                                                      Checks if the instance is in the same month as the current moment next month.
155 * @method        bool             isLastMonth()                                                                      Checks if the instance is in the same month as the current moment last month.
156 * @method        bool             isCurrentQuarter()                                                                 Checks if the instance is in the same quarter as the current moment.
157 * @method        bool             isNextQuarter()                                                                    Checks if the instance is in the same quarter as the current moment next quarter.
158 * @method        bool             isLastQuarter()                                                                    Checks if the instance is in the same quarter as the current moment last quarter.
159 * @method        bool             isSameDecade(Carbon|DateTimeInterface|string|null $date = null)                    Checks if the given date is in the same decade as the instance. If null passed, compare to now (with the same timezone).
160 * @method        bool             isCurrentDecade()                                                                  Checks if the instance is in the same decade as the current moment.
161 * @method        bool             isNextDecade()                                                                     Checks if the instance is in the same decade as the current moment next decade.
162 * @method        bool             isLastDecade()                                                                     Checks if the instance is in the same decade as the current moment last decade.
163 * @method        bool             isSameCentury(Carbon|DateTimeInterface|string|null $date = null)                   Checks if the given date is in the same century as the instance. If null passed, compare to now (with the same timezone).
164 * @method        bool             isCurrentCentury()                                                                 Checks if the instance is in the same century as the current moment.
165 * @method        bool             isNextCentury()                                                                    Checks if the instance is in the same century as the current moment next century.
166 * @method        bool             isLastCentury()                                                                    Checks if the instance is in the same century as the current moment last century.
167 * @method        bool             isSameMillennium(Carbon|DateTimeInterface|string|null $date = null)                Checks if the given date is in the same millennium as the instance. If null passed, compare to now (with the same timezone).
168 * @method        bool             isCurrentMillennium()                                                              Checks if the instance is in the same millennium as the current moment.
169 * @method        bool             isNextMillennium()                                                                 Checks if the instance is in the same millennium as the current moment next millennium.
170 * @method        bool             isLastMillennium()                                                                 Checks if the instance is in the same millennium as the current moment last millennium.
171 * @method        CarbonInterface  years(int $value)                                                                  Set current instance year to the given value.
172 * @method        CarbonInterface  year(int $value)                                                                   Set current instance year to the given value.
173 * @method        CarbonInterface  setYears(int $value)                                                               Set current instance year to the given value.
174 * @method        CarbonInterface  setYear(int $value)                                                                Set current instance year to the given value.
175 * @method        CarbonInterface  months(int $value)                                                                 Set current instance month to the given value.
176 * @method        CarbonInterface  month(int $value)                                                                  Set current instance month to the given value.
177 * @method        CarbonInterface  setMonths(int $value)                                                              Set current instance month to the given value.
178 * @method        CarbonInterface  setMonth(int $value)                                                               Set current instance month to the given value.
179 * @method        CarbonInterface  days(int $value)                                                                   Set current instance day to the given value.
180 * @method        CarbonInterface  day(int $value)                                                                    Set current instance day to the given value.
181 * @method        CarbonInterface  setDays(int $value)                                                                Set current instance day to the given value.
182 * @method        CarbonInterface  setDay(int $value)                                                                 Set current instance day to the given value.
183 * @method        CarbonInterface  hours(int $value)                                                                  Set current instance hour to the given value.
184 * @method        CarbonInterface  hour(int $value)                                                                   Set current instance hour to the given value.
185 * @method        CarbonInterface  setHours(int $value)                                                               Set current instance hour to the given value.
186 * @method        CarbonInterface  setHour(int $value)                                                                Set current instance hour to the given value.
187 * @method        CarbonInterface  minutes(int $value)                                                                Set current instance minute to the given value.
188 * @method        CarbonInterface  minute(int $value)                                                                 Set current instance minute to the given value.
189 * @method        CarbonInterface  setMinutes(int $value)                                                             Set current instance minute to the given value.
190 * @method        CarbonInterface  setMinute(int $value)                                                              Set current instance minute to the given value.
191 * @method        CarbonInterface  seconds(int $value)                                                                Set current instance second to the given value.
192 * @method        CarbonInterface  second(int $value)                                                                 Set current instance second to the given value.
193 * @method        CarbonInterface  setSeconds(int $value)                                                             Set current instance second to the given value.
194 * @method        CarbonInterface  setSecond(int $value)                                                              Set current instance second to the given value.
195 * @method        CarbonInterface  millis(int $value)                                                                 Set current instance millisecond to the given value.
196 * @method        CarbonInterface  milli(int $value)                                                                  Set current instance millisecond to the given value.
197 * @method        CarbonInterface  setMillis(int $value)                                                              Set current instance millisecond to the given value.
198 * @method        CarbonInterface  setMilli(int $value)                                                               Set current instance millisecond to the given value.
199 * @method        CarbonInterface  milliseconds(int $value)                                                           Set current instance millisecond to the given value.
200 * @method        CarbonInterface  millisecond(int $value)                                                            Set current instance millisecond to the given value.
201 * @method        CarbonInterface  setMilliseconds(int $value)                                                        Set current instance millisecond to the given value.
202 * @method        CarbonInterface  setMillisecond(int $value)                                                         Set current instance millisecond to the given value.
203 * @method        CarbonInterface  micros(int $value)                                                                 Set current instance microsecond to the given value.
204 * @method        CarbonInterface  micro(int $value)                                                                  Set current instance microsecond to the given value.
205 * @method        CarbonInterface  setMicros(int $value)                                                              Set current instance microsecond to the given value.
206 * @method        CarbonInterface  setMicro(int $value)                                                               Set current instance microsecond to the given value.
207 * @method        CarbonInterface  microseconds(int $value)                                                           Set current instance microsecond to the given value.
208 * @method        CarbonInterface  microsecond(int $value)                                                            Set current instance microsecond to the given value.
209 * @method        CarbonInterface  setMicroseconds(int $value)                                                        Set current instance microsecond to the given value.
210 * @method        CarbonInterface  setMicrosecond(int $value)                                                         Set current instance microsecond to the given value.
211 * @method        CarbonInterface  addYears(int $value = 1)                                                           Add years (the $value count passed in) to the instance (using date interval).
212 * @method        CarbonInterface  addYear()                                                                          Add one year to the instance (using date interval).
213 * @method        CarbonInterface  subYears(int $value = 1)                                                           Sub years (the $value count passed in) to the instance (using date interval).
214 * @method        CarbonInterface  subYear()                                                                          Sub one year to the instance (using date interval).
215 * @method        CarbonInterface  addYearsWithOverflow(int $value = 1)                                               Add years (the $value count passed in) to the instance (using date interval) with overflow explicitly allowed.
216 * @method        CarbonInterface  addYearWithOverflow()                                                              Add one year to the instance (using date interval) with overflow explicitly allowed.
217 * @method        CarbonInterface  subYearsWithOverflow(int $value = 1)                                               Sub years (the $value count passed in) to the instance (using date interval) with overflow explicitly allowed.
218 * @method        CarbonInterface  subYearWithOverflow()                                                              Sub one year to the instance (using date interval) with overflow explicitly allowed.
219 * @method        CarbonInterface  addYearsWithoutOverflow(int $value = 1)                                            Add years (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
220 * @method        CarbonInterface  addYearWithoutOverflow()                                                           Add one year to the instance (using date interval) with overflow explicitly forbidden.
221 * @method        CarbonInterface  subYearsWithoutOverflow(int $value = 1)                                            Sub years (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
222 * @method        CarbonInterface  subYearWithoutOverflow()                                                           Sub one year to the instance (using date interval) with overflow explicitly forbidden.
223 * @method        CarbonInterface  addYearsWithNoOverflow(int $value = 1)                                             Add years (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
224 * @method        CarbonInterface  addYearWithNoOverflow()                                                            Add one year to the instance (using date interval) with overflow explicitly forbidden.
225 * @method        CarbonInterface  subYearsWithNoOverflow(int $value = 1)                                             Sub years (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
226 * @method        CarbonInterface  subYearWithNoOverflow()                                                            Sub one year to the instance (using date interval) with overflow explicitly forbidden.
227 * @method        CarbonInterface  addYearsNoOverflow(int $value = 1)                                                 Add years (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
228 * @method        CarbonInterface  addYearNoOverflow()                                                                Add one year to the instance (using date interval) with overflow explicitly forbidden.
229 * @method        CarbonInterface  subYearsNoOverflow(int $value = 1)                                                 Sub years (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
230 * @method        CarbonInterface  subYearNoOverflow()                                                                Sub one year to the instance (using date interval) with overflow explicitly forbidden.
231 * @method        CarbonInterface  addMonths(int $value = 1)                                                          Add months (the $value count passed in) to the instance (using date interval).
232 * @method        CarbonInterface  addMonth()                                                                         Add one month to the instance (using date interval).
233 * @method        CarbonInterface  subMonths(int $value = 1)                                                          Sub months (the $value count passed in) to the instance (using date interval).
234 * @method        CarbonInterface  subMonth()                                                                         Sub one month to the instance (using date interval).
235 * @method        CarbonInterface  addMonthsWithOverflow(int $value = 1)                                              Add months (the $value count passed in) to the instance (using date interval) with overflow explicitly allowed.
236 * @method        CarbonInterface  addMonthWithOverflow()                                                             Add one month to the instance (using date interval) with overflow explicitly allowed.
237 * @method        CarbonInterface  subMonthsWithOverflow(int $value = 1)                                              Sub months (the $value count passed in) to the instance (using date interval) with overflow explicitly allowed.
238 * @method        CarbonInterface  subMonthWithOverflow()                                                             Sub one month to the instance (using date interval) with overflow explicitly allowed.
239 * @method        CarbonInterface  addMonthsWithoutOverflow(int $value = 1)                                           Add months (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
240 * @method        CarbonInterface  addMonthWithoutOverflow()                                                          Add one month to the instance (using date interval) with overflow explicitly forbidden.
241 * @method        CarbonInterface  subMonthsWithoutOverflow(int $value = 1)                                           Sub months (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
242 * @method        CarbonInterface  subMonthWithoutOverflow()                                                          Sub one month to the instance (using date interval) with overflow explicitly forbidden.
243 * @method        CarbonInterface  addMonthsWithNoOverflow(int $value = 1)                                            Add months (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
244 * @method        CarbonInterface  addMonthWithNoOverflow()                                                           Add one month to the instance (using date interval) with overflow explicitly forbidden.
245 * @method        CarbonInterface  subMonthsWithNoOverflow(int $value = 1)                                            Sub months (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
246 * @method        CarbonInterface  subMonthWithNoOverflow()                                                           Sub one month to the instance (using date interval) with overflow explicitly forbidden.
247 * @method        CarbonInterface  addMonthsNoOverflow(int $value = 1)                                                Add months (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
248 * @method        CarbonInterface  addMonthNoOverflow()                                                               Add one month to the instance (using date interval) with overflow explicitly forbidden.
249 * @method        CarbonInterface  subMonthsNoOverflow(int $value = 1)                                                Sub months (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
250 * @method        CarbonInterface  subMonthNoOverflow()                                                               Sub one month to the instance (using date interval) with overflow explicitly forbidden.
251 * @method        CarbonInterface  addDays(int $value = 1)                                                            Add days (the $value count passed in) to the instance (using date interval).
252 * @method        CarbonInterface  addDay()                                                                           Add one day to the instance (using date interval).
253 * @method        CarbonInterface  subDays(int $value = 1)                                                            Sub days (the $value count passed in) to the instance (using date interval).
254 * @method        CarbonInterface  subDay()                                                                           Sub one day to the instance (using date interval).
255 * @method        CarbonInterface  addHours(int $value = 1)                                                           Add hours (the $value count passed in) to the instance (using date interval).
256 * @method        CarbonInterface  addHour()                                                                          Add one hour to the instance (using date interval).
257 * @method        CarbonInterface  subHours(int $value = 1)                                                           Sub hours (the $value count passed in) to the instance (using date interval).
258 * @method        CarbonInterface  subHour()                                                                          Sub one hour to the instance (using date interval).
259 * @method        CarbonInterface  addMinutes(int $value = 1)                                                         Add minutes (the $value count passed in) to the instance (using date interval).
260 * @method        CarbonInterface  addMinute()                                                                        Add one minute to the instance (using date interval).
261 * @method        CarbonInterface  subMinutes(int $value = 1)                                                         Sub minutes (the $value count passed in) to the instance (using date interval).
262 * @method        CarbonInterface  subMinute()                                                                        Sub one minute to the instance (using date interval).
263 * @method        CarbonInterface  addSeconds(int $value = 1)                                                         Add seconds (the $value count passed in) to the instance (using date interval).
264 * @method        CarbonInterface  addSecond()                                                                        Add one second to the instance (using date interval).
265 * @method        CarbonInterface  subSeconds(int $value = 1)                                                         Sub seconds (the $value count passed in) to the instance (using date interval).
266 * @method        CarbonInterface  subSecond()                                                                        Sub one second to the instance (using date interval).
267 * @method        CarbonInterface  addMillis(int $value = 1)                                                          Add milliseconds (the $value count passed in) to the instance (using date interval).
268 * @method        CarbonInterface  addMilli()                                                                         Add one millisecond to the instance (using date interval).
269 * @method        CarbonInterface  subMillis(int $value = 1)                                                          Sub milliseconds (the $value count passed in) to the instance (using date interval).
270 * @method        CarbonInterface  subMilli()                                                                         Sub one millisecond to the instance (using date interval).
271 * @method        CarbonInterface  addMilliseconds(int $value = 1)                                                    Add milliseconds (the $value count passed in) to the instance (using date interval).
272 * @method        CarbonInterface  addMillisecond()                                                                   Add one millisecond to the instance (using date interval).
273 * @method        CarbonInterface  subMilliseconds(int $value = 1)                                                    Sub milliseconds (the $value count passed in) to the instance (using date interval).
274 * @method        CarbonInterface  subMillisecond()                                                                   Sub one millisecond to the instance (using date interval).
275 * @method        CarbonInterface  addMicros(int $value = 1)                                                          Add microseconds (the $value count passed in) to the instance (using date interval).
276 * @method        CarbonInterface  addMicro()                                                                         Add one microsecond to the instance (using date interval).
277 * @method        CarbonInterface  subMicros(int $value = 1)                                                          Sub microseconds (the $value count passed in) to the instance (using date interval).
278 * @method        CarbonInterface  subMicro()                                                                         Sub one microsecond to the instance (using date interval).
279 * @method        CarbonInterface  addMicroseconds(int $value = 1)                                                    Add microseconds (the $value count passed in) to the instance (using date interval).
280 * @method        CarbonInterface  addMicrosecond()                                                                   Add one microsecond to the instance (using date interval).
281 * @method        CarbonInterface  subMicroseconds(int $value = 1)                                                    Sub microseconds (the $value count passed in) to the instance (using date interval).
282 * @method        CarbonInterface  subMicrosecond()                                                                   Sub one microsecond to the instance (using date interval).
283 * @method        CarbonInterface  addMillennia(int $value = 1)                                                       Add millennia (the $value count passed in) to the instance (using date interval).
284 * @method        CarbonInterface  addMillennium()                                                                    Add one millennium to the instance (using date interval).
285 * @method        CarbonInterface  subMillennia(int $value = 1)                                                       Sub millennia (the $value count passed in) to the instance (using date interval).
286 * @method        CarbonInterface  subMillennium()                                                                    Sub one millennium to the instance (using date interval).
287 * @method        CarbonInterface  addMillenniaWithOverflow(int $value = 1)                                           Add millennia (the $value count passed in) to the instance (using date interval) with overflow explicitly allowed.
288 * @method        CarbonInterface  addMillenniumWithOverflow()                                                        Add one millennium to the instance (using date interval) with overflow explicitly allowed.
289 * @method        CarbonInterface  subMillenniaWithOverflow(int $value = 1)                                           Sub millennia (the $value count passed in) to the instance (using date interval) with overflow explicitly allowed.
290 * @method        CarbonInterface  subMillenniumWithOverflow()                                                        Sub one millennium to the instance (using date interval) with overflow explicitly allowed.
291 * @method        CarbonInterface  addMillenniaWithoutOverflow(int $value = 1)                                        Add millennia (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
292 * @method        CarbonInterface  addMillenniumWithoutOverflow()                                                     Add one millennium to the instance (using date interval) with overflow explicitly forbidden.
293 * @method        CarbonInterface  subMillenniaWithoutOverflow(int $value = 1)                                        Sub millennia (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
294 * @method        CarbonInterface  subMillenniumWithoutOverflow()                                                     Sub one millennium to the instance (using date interval) with overflow explicitly forbidden.
295 * @method        CarbonInterface  addMillenniaWithNoOverflow(int $value = 1)                                         Add millennia (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
296 * @method        CarbonInterface  addMillenniumWithNoOverflow()                                                      Add one millennium to the instance (using date interval) with overflow explicitly forbidden.
297 * @method        CarbonInterface  subMillenniaWithNoOverflow(int $value = 1)                                         Sub millennia (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
298 * @method        CarbonInterface  subMillenniumWithNoOverflow()                                                      Sub one millennium to the instance (using date interval) with overflow explicitly forbidden.
299 * @method        CarbonInterface  addMillenniaNoOverflow(int $value = 1)                                             Add millennia (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
300 * @method        CarbonInterface  addMillenniumNoOverflow()                                                          Add one millennium to the instance (using date interval) with overflow explicitly forbidden.
301 * @method        CarbonInterface  subMillenniaNoOverflow(int $value = 1)                                             Sub millennia (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
302 * @method        CarbonInterface  subMillenniumNoOverflow()                                                          Sub one millennium to the instance (using date interval) with overflow explicitly forbidden.
303 * @method        CarbonInterface  addCenturies(int $value = 1)                                                       Add centuries (the $value count passed in) to the instance (using date interval).
304 * @method        CarbonInterface  addCentury()                                                                       Add one century to the instance (using date interval).
305 * @method        CarbonInterface  subCenturies(int $value = 1)                                                       Sub centuries (the $value count passed in) to the instance (using date interval).
306 * @method        CarbonInterface  subCentury()                                                                       Sub one century to the instance (using date interval).
307 * @method        CarbonInterface  addCenturiesWithOverflow(int $value = 1)                                           Add centuries (the $value count passed in) to the instance (using date interval) with overflow explicitly allowed.
308 * @method        CarbonInterface  addCenturyWithOverflow()                                                           Add one century to the instance (using date interval) with overflow explicitly allowed.
309 * @method        CarbonInterface  subCenturiesWithOverflow(int $value = 1)                                           Sub centuries (the $value count passed in) to the instance (using date interval) with overflow explicitly allowed.
310 * @method        CarbonInterface  subCenturyWithOverflow()                                                           Sub one century to the instance (using date interval) with overflow explicitly allowed.
311 * @method        CarbonInterface  addCenturiesWithoutOverflow(int $value = 1)                                        Add centuries (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
312 * @method        CarbonInterface  addCenturyWithoutOverflow()                                                        Add one century to the instance (using date interval) with overflow explicitly forbidden.
313 * @method        CarbonInterface  subCenturiesWithoutOverflow(int $value = 1)                                        Sub centuries (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
314 * @method        CarbonInterface  subCenturyWithoutOverflow()                                                        Sub one century to the instance (using date interval) with overflow explicitly forbidden.
315 * @method        CarbonInterface  addCenturiesWithNoOverflow(int $value = 1)                                         Add centuries (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
316 * @method        CarbonInterface  addCenturyWithNoOverflow()                                                         Add one century to the instance (using date interval) with overflow explicitly forbidden.
317 * @method        CarbonInterface  subCenturiesWithNoOverflow(int $value = 1)                                         Sub centuries (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
318 * @method        CarbonInterface  subCenturyWithNoOverflow()                                                         Sub one century to the instance (using date interval) with overflow explicitly forbidden.
319 * @method        CarbonInterface  addCenturiesNoOverflow(int $value = 1)                                             Add centuries (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
320 * @method        CarbonInterface  addCenturyNoOverflow()                                                             Add one century to the instance (using date interval) with overflow explicitly forbidden.
321 * @method        CarbonInterface  subCenturiesNoOverflow(int $value = 1)                                             Sub centuries (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
322 * @method        CarbonInterface  subCenturyNoOverflow()                                                             Sub one century to the instance (using date interval) with overflow explicitly forbidden.
323 * @method        CarbonInterface  addDecades(int $value = 1)                                                         Add decades (the $value count passed in) to the instance (using date interval).
324 * @method        CarbonInterface  addDecade()                                                                        Add one decade to the instance (using date interval).
325 * @method        CarbonInterface  subDecades(int $value = 1)                                                         Sub decades (the $value count passed in) to the instance (using date interval).
326 * @method        CarbonInterface  subDecade()                                                                        Sub one decade to the instance (using date interval).
327 * @method        CarbonInterface  addDecadesWithOverflow(int $value = 1)                                             Add decades (the $value count passed in) to the instance (using date interval) with overflow explicitly allowed.
328 * @method        CarbonInterface  addDecadeWithOverflow()                                                            Add one decade to the instance (using date interval) with overflow explicitly allowed.
329 * @method        CarbonInterface  subDecadesWithOverflow(int $value = 1)                                             Sub decades (the $value count passed in) to the instance (using date interval) with overflow explicitly allowed.
330 * @method        CarbonInterface  subDecadeWithOverflow()                                                            Sub one decade to the instance (using date interval) with overflow explicitly allowed.
331 * @method        CarbonInterface  addDecadesWithoutOverflow(int $value = 1)                                          Add decades (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
332 * @method        CarbonInterface  addDecadeWithoutOverflow()                                                         Add one decade to the instance (using date interval) with overflow explicitly forbidden.
333 * @method        CarbonInterface  subDecadesWithoutOverflow(int $value = 1)                                          Sub decades (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
334 * @method        CarbonInterface  subDecadeWithoutOverflow()                                                         Sub one decade to the instance (using date interval) with overflow explicitly forbidden.
335 * @method        CarbonInterface  addDecadesWithNoOverflow(int $value = 1)                                           Add decades (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
336 * @method        CarbonInterface  addDecadeWithNoOverflow()                                                          Add one decade to the instance (using date interval) with overflow explicitly forbidden.
337 * @method        CarbonInterface  subDecadesWithNoOverflow(int $value = 1)                                           Sub decades (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
338 * @method        CarbonInterface  subDecadeWithNoOverflow()                                                          Sub one decade to the instance (using date interval) with overflow explicitly forbidden.
339 * @method        CarbonInterface  addDecadesNoOverflow(int $value = 1)                                               Add decades (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
340 * @method        CarbonInterface  addDecadeNoOverflow()                                                              Add one decade to the instance (using date interval) with overflow explicitly forbidden.
341 * @method        CarbonInterface  subDecadesNoOverflow(int $value = 1)                                               Sub decades (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
342 * @method        CarbonInterface  subDecadeNoOverflow()                                                              Sub one decade to the instance (using date interval) with overflow explicitly forbidden.
343 * @method        CarbonInterface  addQuarters(int $value = 1)                                                        Add quarters (the $value count passed in) to the instance (using date interval).
344 * @method        CarbonInterface  addQuarter()                                                                       Add one quarter to the instance (using date interval).
345 * @method        CarbonInterface  subQuarters(int $value = 1)                                                        Sub quarters (the $value count passed in) to the instance (using date interval).
346 * @method        CarbonInterface  subQuarter()                                                                       Sub one quarter to the instance (using date interval).
347 * @method        CarbonInterface  addQuartersWithOverflow(int $value = 1)                                            Add quarters (the $value count passed in) to the instance (using date interval) with overflow explicitly allowed.
348 * @method        CarbonInterface  addQuarterWithOverflow()                                                           Add one quarter to the instance (using date interval) with overflow explicitly allowed.
349 * @method        CarbonInterface  subQuartersWithOverflow(int $value = 1)                                            Sub quarters (the $value count passed in) to the instance (using date interval) with overflow explicitly allowed.
350 * @method        CarbonInterface  subQuarterWithOverflow()                                                           Sub one quarter to the instance (using date interval) with overflow explicitly allowed.
351 * @method        CarbonInterface  addQuartersWithoutOverflow(int $value = 1)                                         Add quarters (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
352 * @method        CarbonInterface  addQuarterWithoutOverflow()                                                        Add one quarter to the instance (using date interval) with overflow explicitly forbidden.
353 * @method        CarbonInterface  subQuartersWithoutOverflow(int $value = 1)                                         Sub quarters (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
354 * @method        CarbonInterface  subQuarterWithoutOverflow()                                                        Sub one quarter to the instance (using date interval) with overflow explicitly forbidden.
355 * @method        CarbonInterface  addQuartersWithNoOverflow(int $value = 1)                                          Add quarters (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
356 * @method        CarbonInterface  addQuarterWithNoOverflow()                                                         Add one quarter to the instance (using date interval) with overflow explicitly forbidden.
357 * @method        CarbonInterface  subQuartersWithNoOverflow(int $value = 1)                                          Sub quarters (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
358 * @method        CarbonInterface  subQuarterWithNoOverflow()                                                         Sub one quarter to the instance (using date interval) with overflow explicitly forbidden.
359 * @method        CarbonInterface  addQuartersNoOverflow(int $value = 1)                                              Add quarters (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
360 * @method        CarbonInterface  addQuarterNoOverflow()                                                             Add one quarter to the instance (using date interval) with overflow explicitly forbidden.
361 * @method        CarbonInterface  subQuartersNoOverflow(int $value = 1)                                              Sub quarters (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
362 * @method        CarbonInterface  subQuarterNoOverflow()                                                             Sub one quarter to the instance (using date interval) with overflow explicitly forbidden.
363 * @method        CarbonInterface  addWeeks(int $value = 1)                                                           Add weeks (the $value count passed in) to the instance (using date interval).
364 * @method        CarbonInterface  addWeek()                                                                          Add one week to the instance (using date interval).
365 * @method        CarbonInterface  subWeeks(int $value = 1)                                                           Sub weeks (the $value count passed in) to the instance (using date interval).
366 * @method        CarbonInterface  subWeek()                                                                          Sub one week to the instance (using date interval).
367 * @method        CarbonInterface  addWeekdays(int $value = 1)                                                        Add weekdays (the $value count passed in) to the instance (using date interval).
368 * @method        CarbonInterface  addWeekday()                                                                       Add one weekday to the instance (using date interval).
369 * @method        CarbonInterface  subWeekdays(int $value = 1)                                                        Sub weekdays (the $value count passed in) to the instance (using date interval).
370 * @method        CarbonInterface  subWeekday()                                                                       Sub one weekday to the instance (using date interval).
371 * @method        CarbonInterface  addRealMicros(int $value = 1)                                                      Add microseconds (the $value count passed in) to the instance (using timestamp).
372 * @method        CarbonInterface  addRealMicro()                                                                     Add one microsecond to the instance (using timestamp).
373 * @method        CarbonInterface  subRealMicros(int $value = 1)                                                      Sub microseconds (the $value count passed in) to the instance (using timestamp).
374 * @method        CarbonInterface  subRealMicro()                                                                     Sub one microsecond to the instance (using timestamp).
375 * @method        CarbonPeriod     microsUntil($endDate = null, int $factor = 1)                                      Return an iterable period from current date to given end (string, DateTime or Carbon instance) for each microsecond or every X microseconds if a factor is given.
376 * @method        CarbonInterface  addRealMicroseconds(int $value = 1)                                                Add microseconds (the $value count passed in) to the instance (using timestamp).
377 * @method        CarbonInterface  addRealMicrosecond()                                                               Add one microsecond to the instance (using timestamp).
378 * @method        CarbonInterface  subRealMicroseconds(int $value = 1)                                                Sub microseconds (the $value count passed in) to the instance (using timestamp).
379 * @method        CarbonInterface  subRealMicrosecond()                                                               Sub one microsecond to the instance (using timestamp).
380 * @method        CarbonPeriod     microsecondsUntil($endDate = null, int $factor = 1)                                Return an iterable period from current date to given end (string, DateTime or Carbon instance) for each microsecond or every X microseconds if a factor is given.
381 * @method        CarbonInterface  addRealMillis(int $value = 1)                                                      Add milliseconds (the $value count passed in) to the instance (using timestamp).
382 * @method        CarbonInterface  addRealMilli()                                                                     Add one millisecond to the instance (using timestamp).
383 * @method        CarbonInterface  subRealMillis(int $value = 1)                                                      Sub milliseconds (the $value count passed in) to the instance (using timestamp).
384 * @method        CarbonInterface  subRealMilli()                                                                     Sub one millisecond to the instance (using timestamp).
385 * @method        CarbonPeriod     millisUntil($endDate = null, int $factor = 1)                                      Return an iterable period from current date to given end (string, DateTime or Carbon instance) for each millisecond or every X milliseconds if a factor is given.
386 * @method        CarbonInterface  addRealMilliseconds(int $value = 1)                                                Add milliseconds (the $value count passed in) to the instance (using timestamp).
387 * @method        CarbonInterface  addRealMillisecond()                                                               Add one millisecond to the instance (using timestamp).
388 * @method        CarbonInterface  subRealMilliseconds(int $value = 1)                                                Sub milliseconds (the $value count passed in) to the instance (using timestamp).
389 * @method        CarbonInterface  subRealMillisecond()                                                               Sub one millisecond to the instance (using timestamp).
390 * @method        CarbonPeriod     millisecondsUntil($endDate = null, int $factor = 1)                                Return an iterable period from current date to given end (string, DateTime or Carbon instance) for each millisecond or every X milliseconds if a factor is given.
391 * @method        CarbonInterface  addRealSeconds(int $value = 1)                                                     Add seconds (the $value count passed in) to the instance (using timestamp).
392 * @method        CarbonInterface  addRealSecond()                                                                    Add one second to the instance (using timestamp).
393 * @method        CarbonInterface  subRealSeconds(int $value = 1)                                                     Sub seconds (the $value count passed in) to the instance (using timestamp).
394 * @method        CarbonInterface  subRealSecond()                                                                    Sub one second to the instance (using timestamp).
395 * @method        CarbonPeriod     secondsUntil($endDate = null, int $factor = 1)                                     Return an iterable period from current date to given end (string, DateTime or Carbon instance) for each second or every X seconds if a factor is given.
396 * @method        CarbonInterface  addRealMinutes(int $value = 1)                                                     Add minutes (the $value count passed in) to the instance (using timestamp).
397 * @method        CarbonInterface  addRealMinute()                                                                    Add one minute to the instance (using timestamp).
398 * @method        CarbonInterface  subRealMinutes(int $value = 1)                                                     Sub minutes (the $value count passed in) to the instance (using timestamp).
399 * @method        CarbonInterface  subRealMinute()                                                                    Sub one minute to the instance (using timestamp).
400 * @method        CarbonPeriod     minutesUntil($endDate = null, int $factor = 1)                                     Return an iterable period from current date to given end (string, DateTime or Carbon instance) for each minute or every X minutes if a factor is given.
401 * @method        CarbonInterface  addRealHours(int $value = 1)                                                       Add hours (the $value count passed in) to the instance (using timestamp).
402 * @method        CarbonInterface  addRealHour()                                                                      Add one hour to the instance (using timestamp).
403 * @method        CarbonInterface  subRealHours(int $value = 1)                                                       Sub hours (the $value count passed in) to the instance (using timestamp).
404 * @method        CarbonInterface  subRealHour()                                                                      Sub one hour to the instance (using timestamp).
405 * @method        CarbonPeriod     hoursUntil($endDate = null, int $factor = 1)                                       Return an iterable period from current date to given end (string, DateTime or Carbon instance) for each hour or every X hours if a factor is given.
406 * @method        CarbonInterface  addRealDays(int $value = 1)                                                        Add days (the $value count passed in) to the instance (using timestamp).
407 * @method        CarbonInterface  addRealDay()                                                                       Add one day to the instance (using timestamp).
408 * @method        CarbonInterface  subRealDays(int $value = 1)                                                        Sub days (the $value count passed in) to the instance (using timestamp).
409 * @method        CarbonInterface  subRealDay()                                                                       Sub one day to the instance (using timestamp).
410 * @method        CarbonPeriod     daysUntil($endDate = null, int $factor = 1)                                        Return an iterable period from current date to given end (string, DateTime or Carbon instance) for each day or every X days if a factor is given.
411 * @method        CarbonInterface  addRealWeeks(int $value = 1)                                                       Add weeks (the $value count passed in) to the instance (using timestamp).
412 * @method        CarbonInterface  addRealWeek()                                                                      Add one week to the instance (using timestamp).
413 * @method        CarbonInterface  subRealWeeks(int $value = 1)                                                       Sub weeks (the $value count passed in) to the instance (using timestamp).
414 * @method        CarbonInterface  subRealWeek()                                                                      Sub one week to the instance (using timestamp).
415 * @method        CarbonPeriod     weeksUntil($endDate = null, int $factor = 1)                                       Return an iterable period from current date to given end (string, DateTime or Carbon instance) for each week or every X weeks if a factor is given.
416 * @method        CarbonInterface  addRealMonths(int $value = 1)                                                      Add months (the $value count passed in) to the instance (using timestamp).
417 * @method        CarbonInterface  addRealMonth()                                                                     Add one month to the instance (using timestamp).
418 * @method        CarbonInterface  subRealMonths(int $value = 1)                                                      Sub months (the $value count passed in) to the instance (using timestamp).
419 * @method        CarbonInterface  subRealMonth()                                                                     Sub one month to the instance (using timestamp).
420 * @method        CarbonPeriod     monthsUntil($endDate = null, int $factor = 1)                                      Return an iterable period from current date to given end (string, DateTime or Carbon instance) for each month or every X months if a factor is given.
421 * @method        CarbonInterface  addRealQuarters(int $value = 1)                                                    Add quarters (the $value count passed in) to the instance (using timestamp).
422 * @method        CarbonInterface  addRealQuarter()                                                                   Add one quarter to the instance (using timestamp).
423 * @method        CarbonInterface  subRealQuarters(int $value = 1)                                                    Sub quarters (the $value count passed in) to the instance (using timestamp).
424 * @method        CarbonInterface  subRealQuarter()                                                                   Sub one quarter to the instance (using timestamp).
425 * @method        CarbonPeriod     quartersUntil($endDate = null, int $factor = 1)                                    Return an iterable period from current date to given end (string, DateTime or Carbon instance) for each quarter or every X quarters if a factor is given.
426 * @method        CarbonInterface  addRealYears(int $value = 1)                                                       Add years (the $value count passed in) to the instance (using timestamp).
427 * @method        CarbonInterface  addRealYear()                                                                      Add one year to the instance (using timestamp).
428 * @method        CarbonInterface  subRealYears(int $value = 1)                                                       Sub years (the $value count passed in) to the instance (using timestamp).
429 * @method        CarbonInterface  subRealYear()                                                                      Sub one year to the instance (using timestamp).
430 * @method        CarbonPeriod     yearsUntil($endDate = null, int $factor = 1)                                       Return an iterable period from current date to given end (string, DateTime or Carbon instance) for each year or every X years if a factor is given.
431 * @method        CarbonInterface  addRealDecades(int $value = 1)                                                     Add decades (the $value count passed in) to the instance (using timestamp).
432 * @method        CarbonInterface  addRealDecade()                                                                    Add one decade to the instance (using timestamp).
433 * @method        CarbonInterface  subRealDecades(int $value = 1)                                                     Sub decades (the $value count passed in) to the instance (using timestamp).
434 * @method        CarbonInterface  subRealDecade()                                                                    Sub one decade to the instance (using timestamp).
435 * @method        CarbonPeriod     decadesUntil($endDate = null, int $factor = 1)                                     Return an iterable period from current date to given end (string, DateTime or Carbon instance) for each decade or every X decades if a factor is given.
436 * @method        CarbonInterface  addRealCenturies(int $value = 1)                                                   Add centuries (the $value count passed in) to the instance (using timestamp).
437 * @method        CarbonInterface  addRealCentury()                                                                   Add one century to the instance (using timestamp).
438 * @method        CarbonInterface  subRealCenturies(int $value = 1)                                                   Sub centuries (the $value count passed in) to the instance (using timestamp).
439 * @method        CarbonInterface  subRealCentury()                                                                   Sub one century to the instance (using timestamp).
440 * @method        CarbonPeriod     centuriesUntil($endDate = null, int $factor = 1)                                   Return an iterable period from current date to given end (string, DateTime or Carbon instance) for each century or every X centuries if a factor is given.
441 * @method        CarbonInterface  addRealMillennia(int $value = 1)                                                   Add millennia (the $value count passed in) to the instance (using timestamp).
442 * @method        CarbonInterface  addRealMillennium()                                                                Add one millennium to the instance (using timestamp).
443 * @method        CarbonInterface  subRealMillennia(int $value = 1)                                                   Sub millennia (the $value count passed in) to the instance (using timestamp).
444 * @method        CarbonInterface  subRealMillennium()                                                                Sub one millennium to the instance (using timestamp).
445 * @method        CarbonPeriod     millenniaUntil($endDate = null, int $factor = 1)                                   Return an iterable period from current date to given end (string, DateTime or Carbon instance) for each millennium or every X millennia if a factor is given.
446 * @method        CarbonInterface  roundYear(float $precision = 1, string $function = "round")                        Round the current instance year with given precision using the given function.
447 * @method        CarbonInterface  roundYears(float $precision = 1, string $function = "round")                       Round the current instance year with given precision using the given function.
448 * @method        CarbonInterface  floorYear(float $precision = 1)                                                    Truncate the current instance year with given precision.
449 * @method        CarbonInterface  floorYears(float $precision = 1)                                                   Truncate the current instance year with given precision.
450 * @method        CarbonInterface  ceilYear(float $precision = 1)                                                     Ceil the current instance year with given precision.
451 * @method        CarbonInterface  ceilYears(float $precision = 1)                                                    Ceil the current instance year with given precision.
452 * @method        CarbonInterface  roundMonth(float $precision = 1, string $function = "round")                       Round the current instance month with given precision using the given function.
453 * @method        CarbonInterface  roundMonths(float $precision = 1, string $function = "round")                      Round the current instance month with given precision using the given function.
454 * @method        CarbonInterface  floorMonth(float $precision = 1)                                                   Truncate the current instance month with given precision.
455 * @method        CarbonInterface  floorMonths(float $precision = 1)                                                  Truncate the current instance month with given precision.
456 * @method        CarbonInterface  ceilMonth(float $precision = 1)                                                    Ceil the current instance month with given precision.
457 * @method        CarbonInterface  ceilMonths(float $precision = 1)                                                   Ceil the current instance month with given precision.
458 * @method        CarbonInterface  roundDay(float $precision = 1, string $function = "round")                         Round the current instance day with given precision using the given function.
459 * @method        CarbonInterface  roundDays(float $precision = 1, string $function = "round")                        Round the current instance day with given precision using the given function.
460 * @method        CarbonInterface  floorDay(float $precision = 1)                                                     Truncate the current instance day with given precision.
461 * @method        CarbonInterface  floorDays(float $precision = 1)                                                    Truncate the current instance day with given precision.
462 * @method        CarbonInterface  ceilDay(float $precision = 1)                                                      Ceil the current instance day with given precision.
463 * @method        CarbonInterface  ceilDays(float $precision = 1)                                                     Ceil the current instance day with given precision.
464 * @method        CarbonInterface  roundHour(float $precision = 1, string $function = "round")                        Round the current instance hour with given precision using the given function.
465 * @method        CarbonInterface  roundHours(float $precision = 1, string $function = "round")                       Round the current instance hour with given precision using the given function.
466 * @method        CarbonInterface  floorHour(float $precision = 1)                                                    Truncate the current instance hour with given precision.
467 * @method        CarbonInterface  floorHours(float $precision = 1)                                                   Truncate the current instance hour with given precision.
468 * @method        CarbonInterface  ceilHour(float $precision = 1)                                                     Ceil the current instance hour with given precision.
469 * @method        CarbonInterface  ceilHours(float $precision = 1)                                                    Ceil the current instance hour with given precision.
470 * @method        CarbonInterface  roundMinute(float $precision = 1, string $function = "round")                      Round the current instance minute with given precision using the given function.
471 * @method        CarbonInterface  roundMinutes(float $precision = 1, string $function = "round")                     Round the current instance minute with given precision using the given function.
472 * @method        CarbonInterface  floorMinute(float $precision = 1)                                                  Truncate the current instance minute with given precision.
473 * @method        CarbonInterface  floorMinutes(float $precision = 1)                                                 Truncate the current instance minute with given precision.
474 * @method        CarbonInterface  ceilMinute(float $precision = 1)                                                   Ceil the current instance minute with given precision.
475 * @method        CarbonInterface  ceilMinutes(float $precision = 1)                                                  Ceil the current instance minute with given precision.
476 * @method        CarbonInterface  roundSecond(float $precision = 1, string $function = "round")                      Round the current instance second with given precision using the given function.
477 * @method        CarbonInterface  roundSeconds(float $precision = 1, string $function = "round")                     Round the current instance second with given precision using the given function.
478 * @method        CarbonInterface  floorSecond(float $precision = 1)                                                  Truncate the current instance second with given precision.
479 * @method        CarbonInterface  floorSeconds(float $precision = 1)                                                 Truncate the current instance second with given precision.
480 * @method        CarbonInterface  ceilSecond(float $precision = 1)                                                   Ceil the current instance second with given precision.
481 * @method        CarbonInterface  ceilSeconds(float $precision = 1)                                                  Ceil the current instance second with given precision.
482 * @method        CarbonInterface  roundMillennium(float $precision = 1, string $function = "round")                  Round the current instance millennium with given precision using the given function.
483 * @method        CarbonInterface  roundMillennia(float $precision = 1, string $function = "round")                   Round the current instance millennium with given precision using the given function.
484 * @method        CarbonInterface  floorMillennium(float $precision = 1)                                              Truncate the current instance millennium with given precision.
485 * @method        CarbonInterface  floorMillennia(float $precision = 1)                                               Truncate the current instance millennium with given precision.
486 * @method        CarbonInterface  ceilMillennium(float $precision = 1)                                               Ceil the current instance millennium with given precision.
487 * @method        CarbonInterface  ceilMillennia(float $precision = 1)                                                Ceil the current instance millennium with given precision.
488 * @method        CarbonInterface  roundCentury(float $precision = 1, string $function = "round")                     Round the current instance century with given precision using the given function.
489 * @method        CarbonInterface  roundCenturies(float $precision = 1, string $function = "round")                   Round the current instance century with given precision using the given function.
490 * @method        CarbonInterface  floorCentury(float $precision = 1)                                                 Truncate the current instance century with given precision.
491 * @method        CarbonInterface  floorCenturies(float $precision = 1)                                               Truncate the current instance century with given precision.
492 * @method        CarbonInterface  ceilCentury(float $precision = 1)                                                  Ceil the current instance century with given precision.
493 * @method        CarbonInterface  ceilCenturies(float $precision = 1)                                                Ceil the current instance century with given precision.
494 * @method        CarbonInterface  roundDecade(float $precision = 1, string $function = "round")                      Round the current instance decade with given precision using the given function.
495 * @method        CarbonInterface  roundDecades(float $precision = 1, string $function = "round")                     Round the current instance decade with given precision using the given function.
496 * @method        CarbonInterface  floorDecade(float $precision = 1)                                                  Truncate the current instance decade with given precision.
497 * @method        CarbonInterface  floorDecades(float $precision = 1)                                                 Truncate the current instance decade with given precision.
498 * @method        CarbonInterface  ceilDecade(float $precision = 1)                                                   Ceil the current instance decade with given precision.
499 * @method        CarbonInterface  ceilDecades(float $precision = 1)                                                  Ceil the current instance decade with given precision.
500 * @method        CarbonInterface  roundQuarter(float $precision = 1, string $function = "round")                     Round the current instance quarter with given precision using the given function.
501 * @method        CarbonInterface  roundQuarters(float $precision = 1, string $function = "round")                    Round the current instance quarter with given precision using the given function.
502 * @method        CarbonInterface  floorQuarter(float $precision = 1)                                                 Truncate the current instance quarter with given precision.
503 * @method        CarbonInterface  floorQuarters(float $precision = 1)                                                Truncate the current instance quarter with given precision.
504 * @method        CarbonInterface  ceilQuarter(float $precision = 1)                                                  Ceil the current instance quarter with given precision.
505 * @method        CarbonInterface  ceilQuarters(float $precision = 1)                                                 Ceil the current instance quarter with given precision.
506 * @method        CarbonInterface  roundMillisecond(float $precision = 1, string $function = "round")                 Round the current instance millisecond with given precision using the given function.
507 * @method        CarbonInterface  roundMilliseconds(float $precision = 1, string $function = "round")                Round the current instance millisecond with given precision using the given function.
508 * @method        CarbonInterface  floorMillisecond(float $precision = 1)                                             Truncate the current instance millisecond with given precision.
509 * @method        CarbonInterface  floorMilliseconds(float $precision = 1)                                            Truncate the current instance millisecond with given precision.
510 * @method        CarbonInterface  ceilMillisecond(float $precision = 1)                                              Ceil the current instance millisecond with given precision.
511 * @method        CarbonInterface  ceilMilliseconds(float $precision = 1)                                             Ceil the current instance millisecond with given precision.
512 * @method        CarbonInterface  roundMicrosecond(float $precision = 1, string $function = "round")                 Round the current instance microsecond with given precision using the given function.
513 * @method        CarbonInterface  roundMicroseconds(float $precision = 1, string $function = "round")                Round the current instance microsecond with given precision using the given function.
514 * @method        CarbonInterface  floorMicrosecond(float $precision = 1)                                             Truncate the current instance microsecond with given precision.
515 * @method        CarbonInterface  floorMicroseconds(float $precision = 1)                                            Truncate the current instance microsecond with given precision.
516 * @method        CarbonInterface  ceilMicrosecond(float $precision = 1)                                              Ceil the current instance microsecond with given precision.
517 * @method        CarbonInterface  ceilMicroseconds(float $precision = 1)                                             Ceil the current instance microsecond with given precision.
518 * @method        string           shortAbsoluteDiffForHumans(DateTimeInterface $other = null, int $parts = 1)        Get the difference (short format, 'Absolute' mode) in a human readable format in the current locale. ($other and $parts parameters can be swapped.)
519 * @method        string           longAbsoluteDiffForHumans(DateTimeInterface $other = null, int $parts = 1)         Get the difference (long format, 'Absolute' mode) in a human readable format in the current locale. ($other and $parts parameters can be swapped.)
520 * @method        string           shortRelativeDiffForHumans(DateTimeInterface $other = null, int $parts = 1)        Get the difference (short format, 'Relative' mode) in a human readable format in the current locale. ($other and $parts parameters can be swapped.)
521 * @method        string           longRelativeDiffForHumans(DateTimeInterface $other = null, int $parts = 1)         Get the difference (long format, 'Relative' mode) in a human readable format in the current locale. ($other and $parts parameters can be swapped.)
522 * @method        string           shortRelativeToNowDiffForHumans(DateTimeInterface $other = null, int $parts = 1)   Get the difference (short format, 'RelativeToNow' mode) in a human readable format in the current locale. ($other and $parts parameters can be swapped.)
523 * @method        string           longRelativeToNowDiffForHumans(DateTimeInterface $other = null, int $parts = 1)    Get the difference (long format, 'RelativeToNow' mode) in a human readable format in the current locale. ($other and $parts parameters can be swapped.)
524 * @method        string           shortRelativeToOtherDiffForHumans(DateTimeInterface $other = null, int $parts = 1) Get the difference (short format, 'RelativeToOther' mode) in a human readable format in the current locale. ($other and $parts parameters can be swapped.)
525 * @method        string           longRelativeToOtherDiffForHumans(DateTimeInterface $other = null, int $parts = 1)  Get the difference (long format, 'RelativeToOther' mode) in a human readable format in the current locale. ($other and $parts parameters can be swapped.)
526 *
527 * </autodoc>
528 */
529trait Date
530{
531    use Boundaries;
532    use Comparison;
533    use Converter;
534    use Creator;
535    use Difference;
536    use Macro;
537    use Modifiers;
538    use Mutability;
539    use ObjectInitialisation;
540    use Options;
541    use Rounding;
542    use Serialization;
543    use Test;
544    use Timestamp;
545    use Units;
546    use Week;
547
548    /**
549     * Names of days of the week.
550     *
551     * @var array
552     */
553    protected static $days = [
554        // @call isDayOfWeek
555        CarbonInterface::SUNDAY => 'Sunday',
556        // @call isDayOfWeek
557        CarbonInterface::MONDAY => 'Monday',
558        // @call isDayOfWeek
559        CarbonInterface::TUESDAY => 'Tuesday',
560        // @call isDayOfWeek
561        CarbonInterface::WEDNESDAY => 'Wednesday',
562        // @call isDayOfWeek
563        CarbonInterface::THURSDAY => 'Thursday',
564        // @call isDayOfWeek
565        CarbonInterface::FRIDAY => 'Friday',
566        // @call isDayOfWeek
567        CarbonInterface::SATURDAY => 'Saturday',
568    ];
569
570    /**
571     * Will UTF8 encoding be used to print localized date/time ?
572     *
573     * @var bool
574     */
575    protected static $utf8 = false;
576
577    /**
578     * List of unit and magic methods associated as doc-comments.
579     *
580     * @var array
581     */
582    protected static $units = [
583        // @call setUnit
584        // @call addUnit
585        'year',
586        // @call setUnit
587        // @call addUnit
588        'month',
589        // @call setUnit
590        // @call addUnit
591        'day',
592        // @call setUnit
593        // @call addUnit
594        'hour',
595        // @call setUnit
596        // @call addUnit
597        'minute',
598        // @call setUnit
599        // @call addUnit
600        'second',
601        // @call setUnit
602        // @call addUnit
603        'milli',
604        // @call setUnit
605        // @call addUnit
606        'millisecond',
607        // @call setUnit
608        // @call addUnit
609        'micro',
610        // @call setUnit
611        // @call addUnit
612        'microsecond',
613    ];
614
615    /**
616     * Creates a DateTimeZone from a string, DateTimeZone or integer offset.
617     *
618     * @param DateTimeZone|string|int|null $object     original value to get CarbonTimeZone from it.
619     * @param DateTimeZone|string|int|null $objectDump dump of the object for error messages.
620     *
621     * @throws InvalidTimeZoneException
622     *
623     * @return CarbonTimeZone|false
624     */
625    protected static function safeCreateDateTimeZone($object, $objectDump = null)
626    {
627        return CarbonTimeZone::instance($object, $objectDump);
628    }
629
630    /**
631     * Get the TimeZone associated with the Carbon instance (as CarbonTimeZone).
632     *
633     * @return CarbonTimeZone
634     *
635     * @link https://php.net/manual/en/datetime.gettimezone.php
636     */
637    #[ReturnTypeWillChange]
638    public function getTimezone()
639    {
640        return CarbonTimeZone::instance(parent::getTimezone());
641    }
642
643    /**
644     * List of minimum and maximums for each unit.
645     *
646     * @return array
647     */
648    protected static function getRangesByUnit()
649    {
650        return [
651            // @call roundUnit
652            'year' => [1, 9999],
653            // @call roundUnit
654            'month' => [1, static::MONTHS_PER_YEAR],
655            // @call roundUnit
656            'day' => [1, 31],
657            // @call roundUnit
658            'hour' => [0, static::HOURS_PER_DAY - 1],
659            // @call roundUnit
660            'minute' => [0, static::MINUTES_PER_HOUR - 1],
661            // @call roundUnit
662            'second' => [0, static::SECONDS_PER_MINUTE - 1],
663        ];
664    }
665
666    /**
667     * Get a copy of the instance.
668     *
669     * @return static
670     */
671    public function copy()
672    {
673        return clone $this;
674    }
675
676    /**
677     * @alias copy
678     *
679     * Get a copy of the instance.
680     *
681     * @return static
682     */
683    public function clone()
684    {
685        return clone $this;
686    }
687
688    /**
689     * Clone the current instance if it's mutable.
690     *
691     * This method is convenient to ensure you don't mutate the initial object
692     * but avoid to make a useless copy of it if it's already immutable.
693     *
694     * @return static
695     */
696    public function avoidMutation(): self
697    {
698        if ($this instanceof DateTimeImmutable) {
699            return $this;
700        }
701
702        return clone $this;
703    }
704
705    /**
706     * Returns a present instance in the same timezone.
707     *
708     * @return static
709     */
710    public function nowWithSameTz()
711    {
712        return static::now($this->getTimezone());
713    }
714
715    /**
716     * Throws an exception if the given object is not a DateTime and does not implement DateTimeInterface.
717     *
718     * @param mixed        $date
719     * @param string|array $other
720     *
721     * @throws InvalidTypeException
722     */
723    protected static function expectDateTime($date, $other = [])
724    {
725        $message = 'Expected ';
726        foreach ((array) $other as $expect) {
727            $message .= "$expect, ";
728        }
729
730        if (!$date instanceof DateTime && !$date instanceof DateTimeInterface) {
731            throw new InvalidTypeException(
732                $message.'DateTime or DateTimeInterface, '.
733                (\is_object($date) ? \get_class($date) : \gettype($date)).' given'
734            );
735        }
736    }
737
738    /**
739     * Return the Carbon instance passed through, a now instance in the same timezone
740     * if null given or parse the input if string given.
741     *
742     * @param Carbon|DateTimeInterface|string|null $date
743     *
744     * @return static
745     */
746    protected function resolveCarbon($date = null)
747    {
748        if (!$date) {
749            return $this->nowWithSameTz();
750        }
751
752        if (\is_string($date)) {
753            return static::parse($date, $this->getTimezone());
754        }
755
756        static::expectDateTime($date, ['null', 'string']);
757
758        return $date instanceof self ? $date : static::instance($date);
759    }
760
761    /**
762     * Return the Carbon instance passed through, a now instance in UTC
763     * if null given or parse the input if string given (using current timezone
764     * then switching to UTC).
765     *
766     * @param Carbon|DateTimeInterface|string|null $date
767     *
768     * @return static
769     */
770    protected function resolveUTC($date = null): self
771    {
772        if (!$date) {
773            return static::now('UTC');
774        }
775
776        if (\is_string($date)) {
777            return static::parse($date, $this->getTimezone())->utc();
778        }
779
780        static::expectDateTime($date, ['null', 'string']);
781
782        return $date instanceof self ? $date : static::instance($date)->utc();
783    }
784
785    /**
786     * Return the Carbon instance passed through, a now instance in the same timezone
787     * if null given or parse the input if string given.
788     *
789     * @param Carbon|\Carbon\CarbonPeriod|\Carbon\CarbonInterval|\DateInterval|\DatePeriod|DateTimeInterface|string|null $date
790     *
791     * @return static
792     */
793    public function carbonize($date = null)
794    {
795        if ($date instanceof DateInterval) {
796            return $this->avoidMutation()->add($date);
797        }
798
799        if ($date instanceof DatePeriod || $date instanceof CarbonPeriod) {
800            $date = $date->getStartDate();
801        }
802
803        return $this->resolveCarbon($date);
804    }
805
806    ///////////////////////////////////////////////////////////////////
807    ///////////////////////// GETTERS AND SETTERS /////////////////////
808    ///////////////////////////////////////////////////////////////////
809
810    /**
811     * Get a part of the Carbon object
812     *
813     * @param string $name
814     *
815     * @throws UnknownGetterException
816     *
817     * @return string|int|bool|DateTimeZone|null
818     */
819    public function __get($name)
820    {
821        return $this->get($name);
822    }
823
824    /**
825     * Get a part of the Carbon object
826     *
827     * @param string $name
828     *
829     * @throws UnknownGetterException
830     *
831     * @return string|int|bool|DateTimeZone|null
832     */
833    public function get($name)
834    {
835        static $formats = [
836            // @property int
837            'year' => 'Y',
838            // @property int
839            'yearIso' => 'o',
840            // @property int
841            // @call isSameUnit
842            'month' => 'n',
843            // @property int
844            'day' => 'j',
845            // @property int
846            'hour' => 'G',
847            // @property int
848            'minute' => 'i',
849            // @property int
850            'second' => 's',
851            // @property int
852            'micro' => 'u',
853            // @property int
854            'microsecond' => 'u',
855            // @property-read int 0 (for Sunday) through 6 (for Saturday)
856            'dayOfWeek' => 'w',
857            // @property-read int 1 (for Monday) through 7 (for Sunday)
858            'dayOfWeekIso' => 'N',
859            // @property-read int ISO-8601 week number of year, weeks starting on Monday
860            'weekOfYear' => 'W',
861            // @property-read int number of days in the given month
862            'daysInMonth' => 't',
863            // @property int|float|string seconds since the Unix Epoch
864            'timestamp' => 'U',
865            // @property-read string "am"/"pm" (Ante meridiem or Post meridiem latin lowercase mark)
866            'latinMeridiem' => 'a',
867            // @property-read string "AM"/"PM" (Ante meridiem or Post meridiem latin uppercase mark)
868            'latinUpperMeridiem' => 'A',
869            // @property string the day of week in English
870            'englishDayOfWeek' => 'l',
871            // @property string the abbreviated day of week in English
872            'shortEnglishDayOfWeek' => 'D',
873            // @property string the month in English
874            'englishMonth' => 'F',
875            // @property string the abbreviated month in English
876            'shortEnglishMonth' => 'M',
877            // @property string the day of week in current locale LC_TIME
878            'localeDayOfWeek' => '%A',
879            // @property string the abbreviated day of week in current locale LC_TIME
880            'shortLocaleDayOfWeek' => '%a',
881            // @property string the month in current locale LC_TIME
882            'localeMonth' => '%B',
883            // @property string the abbreviated month in current locale LC_TIME
884            'shortLocaleMonth' => '%b',
885            // @property-read string $timezoneAbbreviatedName the current timezone abbreviated name
886            'timezoneAbbreviatedName' => 'T',
887            // @property-read string $tzAbbrName alias of $timezoneAbbreviatedName
888            'tzAbbrName' => 'T',
889        ];
890
891        switch (true) {
892            case isset($formats[$name]):
893                $format = $formats[$name];
894                $method = str_starts_with($format, '%') ? 'formatLocalized' : 'rawFormat';
895                $value = $this->$method($format);
896
897                return is_numeric($value) ? (int) $value : $value;
898
899            // @property-read string long name of weekday translated according to Carbon locale, in english if no translation available for current language
900            case $name === 'dayName':
901                return $this->getTranslatedDayName();
902            // @property-read string short name of weekday translated according to Carbon locale, in english if no translation available for current language
903            case $name === 'shortDayName':
904                return $this->getTranslatedShortDayName();
905            // @property-read string very short name of weekday translated according to Carbon locale, in english if no translation available for current language
906            case $name === 'minDayName':
907                return $this->getTranslatedMinDayName();
908            // @property-read string long name of month translated according to Carbon locale, in english if no translation available for current language
909            case $name === 'monthName':
910                return $this->getTranslatedMonthName();
911            // @property-read string short name of month translated according to Carbon locale, in english if no translation available for current language
912            case $name === 'shortMonthName':
913                return $this->getTranslatedShortMonthName();
914            // @property-read string lowercase meridiem mark translated according to Carbon locale, in latin if no translation available for current language
915            case $name === 'meridiem':
916                return $this->meridiem(true);
917            // @property-read string uppercase meridiem mark translated according to Carbon locale, in latin if no translation available for current language
918            case $name === 'upperMeridiem':
919                return $this->meridiem();
920            // @property-read int current hour from 1 to 24
921            case $name === 'noZeroHour':
922                return $this->hour ?: 24;
923            // @property int
924            case $name === 'milliseconds':
925                // @property int
926            case $name === 'millisecond':
927            // @property int
928            case $name === 'milli':
929                return (int) floor($this->rawFormat('u') / 1000);
930
931            // @property int 1 through 53
932            case $name === 'week':
933                return (int) $this->week();
934
935            // @property int 1 through 53
936            case $name === 'isoWeek':
937                return (int) $this->isoWeek();
938
939            // @property int year according to week format
940            case $name === 'weekYear':
941                return (int) $this->weekYear();
942
943            // @property int year according to ISO week format
944            case $name === 'isoWeekYear':
945                return (int) $this->isoWeekYear();
946
947            // @property-read int 51 through 53
948            case $name === 'weeksInYear':
949                return $this->weeksInYear();
950
951            // @property-read int 51 through 53
952            case $name === 'isoWeeksInYear':
953                return $this->isoWeeksInYear();
954
955            // @property-read int 1 through 5
956            case $name === 'weekOfMonth':
957                return (int) ceil($this->day / static::DAYS_PER_WEEK);
958
959            // @property-read int 1 through 5
960            case $name === 'weekNumberInMonth':
961                return (int) ceil(($this->day + $this->avoidMutation()->startOfMonth()->dayOfWeekIso - 1) / static::DAYS_PER_WEEK);
962
963            // @property-read int 0 through 6
964            case $name === 'firstWeekDay':
965                return $this->localTranslator ? ($this->getTranslationMessage('first_day_of_week') ?? 0) : static::getWeekStartsAt();
966
967            // @property-read int 0 through 6
968            case $name === 'lastWeekDay':
969                return $this->localTranslator ? (($this->getTranslationMessage('first_day_of_week') ?? 0) + static::DAYS_PER_WEEK - 1) % static::DAYS_PER_WEEK : static::getWeekEndsAt();
970
971            // @property int 1 through 366
972            case $name === 'dayOfYear':
973                return 1 + (int) ($this->rawFormat('z'));
974
975            // @property-read int 365 or 366
976            case $name === 'daysInYear':
977                return $this->isLeapYear() ? 366 : 365;
978
979            // @property int does a diffInYears() with default parameters
980            case $name === 'age':
981                return $this->diffInYears();
982
983            // @property-read int the quarter of this instance, 1 - 4
984            // @call isSameUnit
985            case $name === 'quarter':
986                return (int) ceil($this->month / static::MONTHS_PER_QUARTER);
987
988            // @property-read int the decade of this instance
989            // @call isSameUnit
990            case $name === 'decade':
991                return (int) ceil($this->year / static::YEARS_PER_DECADE);
992
993            // @property-read int the century of this instance
994            // @call isSameUnit
995            case $name === 'century':
996                $factor = 1;
997                $year = $this->year;
998                if ($year < 0) {
999                    $year = -$year;
1000                    $factor = -1;
1001                }
1002
1003                return (int) ($factor * ceil($year / static::YEARS_PER_CENTURY));
1004
1005            // @property-read int the millennium of this instance
1006            // @call isSameUnit
1007            case $name === 'millennium':
1008                $factor = 1;
1009                $year = $this->year;
1010                if ($year < 0) {
1011                    $year = -$year;
1012                    $factor = -1;
1013                }
1014
1015                return (int) ($factor * ceil($year / static::YEARS_PER_MILLENNIUM));
1016
1017            // @property int the timezone offset in seconds from UTC
1018            case $name === 'offset':
1019                return $this->getOffset();
1020
1021            // @property int the timezone offset in minutes from UTC
1022            case $name === 'offsetMinutes':
1023                return $this->getOffset() / static::SECONDS_PER_MINUTE;
1024
1025            // @property int the timezone offset in hours from UTC
1026            case $name === 'offsetHours':
1027                return $this->getOffset() / static::SECONDS_PER_MINUTE / static::MINUTES_PER_HOUR;
1028
1029            // @property-read bool daylight savings time indicator, true if DST, false otherwise
1030            case $name === 'dst':
1031                return $this->rawFormat('I') === '1';
1032
1033            // @property-read bool checks if the timezone is local, true if local, false otherwise
1034            case $name === 'local':
1035                return $this->getOffset() === $this->avoidMutation()->setTimezone(date_default_timezone_get())->getOffset();
1036
1037            // @property-read bool checks if the timezone is UTC, true if UTC, false otherwise
1038            case $name === 'utc':
1039                return $this->getOffset() === 0;
1040
1041            // @property CarbonTimeZone $timezone the current timezone
1042            // @property CarbonTimeZone $tz alias of $timezone
1043            case $name === 'timezone' || $name === 'tz':
1044                return CarbonTimeZone::instance($this->getTimezone());
1045
1046            // @property-read string $timezoneName the current timezone name
1047            // @property-read string $tzName alias of $timezoneName
1048            case $name === 'timezoneName' || $name === 'tzName':
1049                return $this->getTimezone()->getName();
1050
1051            // @property-read string locale of the current instance
1052            case $name === 'locale':
1053                return $this->getTranslatorLocale();
1054
1055            default:
1056                $macro = $this->getLocalMacro('get'.ucfirst($name));
1057
1058                if ($macro) {
1059                    return $this->executeCallableWithContext($macro);
1060                }
1061
1062                throw new UnknownGetterException($name);
1063        }
1064    }
1065
1066    /**
1067     * Check if an attribute exists on the object
1068     *
1069     * @param string $name
1070     *
1071     * @return bool
1072     */
1073    public function __isset($name)
1074    {
1075        try {
1076            $this->__get($name);
1077        } catch (UnknownGetterException | ReflectionException $e) {
1078            return false;
1079        }
1080
1081        return true;
1082    }
1083
1084    /**
1085     * Set a part of the Carbon object
1086     *
1087     * @param string                  $name
1088     * @param string|int|DateTimeZone $value
1089     *
1090     * @throws UnknownSetterException|ReflectionException
1091     *
1092     * @return void
1093     */
1094    public function __set($name, $value)
1095    {
1096        if ($this->constructedObjectId === spl_object_hash($this)) {
1097            $this->set($name, $value);
1098
1099            return;
1100        }
1101
1102        $this->$name = $value;
1103    }
1104
1105    /**
1106     * Set a part of the Carbon object
1107     *
1108     * @param string|array            $name
1109     * @param string|int|DateTimeZone $value
1110     *
1111     * @throws ImmutableException|UnknownSetterException
1112     *
1113     * @return $this
1114     */
1115    public function set($name, $value = null)
1116    {
1117        if ($this->isImmutable()) {
1118            throw new ImmutableException(sprintf('%s class', static::class));
1119        }
1120
1121        if (\is_array($name)) {
1122            foreach ($name as $key => $value) {
1123                $this->set($key, $value);
1124            }
1125
1126            return $this;
1127        }
1128
1129        switch ($name) {
1130            case 'milliseconds':
1131            case 'millisecond':
1132            case 'milli':
1133            case 'microseconds':
1134            case 'microsecond':
1135            case 'micro':
1136                if (str_starts_with($name, 'milli')) {
1137                    $value *= 1000;
1138                }
1139
1140                while ($value < 0) {
1141                    $this->subSecond();
1142                    $value += static::MICROSECONDS_PER_SECOND;
1143                }
1144
1145                while ($value >= static::MICROSECONDS_PER_SECOND) {
1146                    $this->addSecond();
1147                    $value -= static::MICROSECONDS_PER_SECOND;
1148                }
1149
1150                $this->modify($this->rawFormat('H:i:s.').str_pad((string) round($value), 6, '0', STR_PAD_LEFT));
1151
1152                break;
1153
1154            case 'year':
1155            case 'month':
1156            case 'day':
1157            case 'hour':
1158            case 'minute':
1159            case 'second':
1160                [$year, $month, $day, $hour, $minute, $second] = array_map('intval', explode('-', $this->rawFormat('Y-n-j-G-i-s')));
1161                $$name = $value;
1162                $this->setDateTime($year, $month, $day, $hour, $minute, $second);
1163
1164                break;
1165
1166            case 'week':
1167                $this->week($value);
1168
1169                break;
1170
1171            case 'isoWeek':
1172                $this->isoWeek($value);
1173
1174                break;
1175
1176            case 'weekYear':
1177                $this->weekYear($value);
1178
1179                break;
1180
1181            case 'isoWeekYear':
1182                $this->isoWeekYear($value);
1183
1184                break;
1185
1186            case 'dayOfYear':
1187                $this->addDays($value - $this->dayOfYear);
1188
1189                break;
1190
1191            case 'timestamp':
1192                $this->setTimestamp($value);
1193
1194                break;
1195
1196            case 'offset':
1197                $this->setTimezone(static::safeCreateDateTimeZone($value / static::SECONDS_PER_MINUTE / static::MINUTES_PER_HOUR));
1198
1199                break;
1200
1201            case 'offsetMinutes':
1202                $this->setTimezone(static::safeCreateDateTimeZone($value / static::MINUTES_PER_HOUR));
1203
1204                break;
1205
1206            case 'offsetHours':
1207                $this->setTimezone(static::safeCreateDateTimeZone($value));
1208
1209                break;
1210
1211            case 'timezone':
1212            case 'tz':
1213                $this->setTimezone($value);
1214
1215                break;
1216
1217            default:
1218                $macro = $this->getLocalMacro('set'.ucfirst($name));
1219
1220                if ($macro) {
1221                    $this->executeCallableWithContext($macro, $value);
1222
1223                    break;
1224                }
1225
1226                if ($this->localStrictModeEnabled ?? static::isStrictModeEnabled()) {
1227                    throw new UnknownSetterException($name);
1228                }
1229
1230                $this->$name = $value;
1231        }
1232
1233        return $this;
1234    }
1235
1236    protected function getTranslatedFormByRegExp($baseKey, $keySuffix, $context, $subKey, $defaultValue)
1237    {
1238        $key = $baseKey.$keySuffix;
1239        $standaloneKey = "${key}_standalone";
1240        $baseTranslation = $this->getTranslationMessage($key);
1241
1242        if ($baseTranslation instanceof Closure) {
1243            return $baseTranslation($this, $context, $subKey) ?: $defaultValue;
1244        }
1245
1246        if (
1247            $this->getTranslationMessage("$standaloneKey.$subKey") &&
1248            (!$context || ($regExp = $this->getTranslationMessage("${baseKey}_regexp")) && !preg_match($regExp, $context))
1249        ) {
1250            $key = $standaloneKey;
1251        }
1252
1253        return $this->getTranslationMessage("$key.$subKey", null, $defaultValue);
1254    }
1255
1256    /**
1257     * Get the translation of the current week day name (with context for languages with multiple forms).
1258     *
1259     * @param string|null $context      whole format string
1260     * @param string      $keySuffix    "", "_short" or "_min"
1261     * @param string|null $defaultValue default value if translation missing
1262     *
1263     * @return string
1264     */
1265    public function getTranslatedDayName($context = null, $keySuffix = '', $defaultValue = null)
1266    {
1267        return $this->getTranslatedFormByRegExp('weekdays', $keySuffix, $context, $this->dayOfWeek, $defaultValue ?: $this->englishDayOfWeek);
1268    }
1269
1270    /**
1271     * Get the translation of the current short week day name (with context for languages with multiple forms).
1272     *
1273     * @param string|null $context whole format string
1274     *
1275     * @return string
1276     */
1277    public function getTranslatedShortDayName($context = null)
1278    {
1279        return $this->getTranslatedDayName($context, '_short', $this->shortEnglishDayOfWeek);
1280    }
1281
1282    /**
1283     * Get the translation of the current abbreviated week day name (with context for languages with multiple forms).
1284     *
1285     * @param string|null $context whole format string
1286     *
1287     * @return string
1288     */
1289    public function getTranslatedMinDayName($context = null)
1290    {
1291        return $this->getTranslatedDayName($context, '_min', $this->shortEnglishDayOfWeek);
1292    }
1293
1294    /**
1295     * Get the translation of the current month day name (with context for languages with multiple forms).
1296     *
1297     * @param string|null $context      whole format string
1298     * @param string      $keySuffix    "" or "_short"
1299     * @param string|null $defaultValue default value if translation missing
1300     *
1301     * @return string
1302     */
1303    public function getTranslatedMonthName($context = null, $keySuffix = '', $defaultValue = null)
1304    {
1305        return $this->getTranslatedFormByRegExp('months', $keySuffix, $context, $this->month - 1, $defaultValue ?: $this->englishMonth);
1306    }
1307
1308    /**
1309     * Get the translation of the current short month day name (with context for languages with multiple forms).
1310     *
1311     * @param string|null $context whole format string
1312     *
1313     * @return string
1314     */
1315    public function getTranslatedShortMonthName($context = null)
1316    {
1317        return $this->getTranslatedMonthName($context, '_short', $this->shortEnglishMonth);
1318    }
1319
1320    /**
1321     * Get/set the day of year.
1322     *
1323     * @param int|null $value new value for day of year if using as setter.
1324     *
1325     * @return static|int
1326     */
1327    public function dayOfYear($value = null)
1328    {
1329        $dayOfYear = $this->dayOfYear;
1330
1331        return $value === null ? $dayOfYear : $this->addDays($value - $dayOfYear);
1332    }
1333
1334    /**
1335     * Get/set the weekday from 0 (Sunday) to 6 (Saturday).
1336     *
1337     * @param int|null $value new value for weekday if using as setter.
1338     *
1339     * @return static|int
1340     */
1341    public function weekday($value = null)
1342    {
1343        $dayOfWeek = ($this->dayOfWeek + 7 - (int) ($this->getTranslationMessage('first_day_of_week') ?? 0)) % 7;
1344
1345        return $value === null ? $dayOfWeek : $this->addDays($value - $dayOfWeek);
1346    }
1347
1348    /**
1349     * Get/set the ISO weekday from 1 (Monday) to 7 (Sunday).
1350     *
1351     * @param int|null $value new value for weekday if using as setter.
1352     *
1353     * @return static|int
1354     */
1355    public function isoWeekday($value = null)
1356    {
1357        $dayOfWeekIso = $this->dayOfWeekIso;
1358
1359        return $value === null ? $dayOfWeekIso : $this->addDays($value - $dayOfWeekIso);
1360    }
1361
1362    /**
1363     * Set any unit to a new value without overflowing current other unit given.
1364     *
1365     * @param string $valueUnit    unit name to modify
1366     * @param int    $value        new value for the input unit
1367     * @param string $overflowUnit unit name to not overflow
1368     *
1369     * @return static
1370     */
1371    public function setUnitNoOverflow($valueUnit, $value, $overflowUnit)
1372    {
1373        try {
1374            $original = $this->avoidMutation();
1375            /** @var static $date */
1376            $date = $this->$valueUnit($value);
1377            $end = $original->avoidMutation()->endOf($overflowUnit);
1378            $start = $original->avoidMutation()->startOf($overflowUnit);
1379            if ($date < $start) {
1380                $date = $date->setDateTimeFrom($start);
1381            } elseif ($date > $end) {
1382                $date = $date->setDateTimeFrom($end);
1383            }
1384
1385            return $date;
1386        } catch (BadMethodCallException | ReflectionException $exception) {
1387            throw new UnknownUnitException($valueUnit, 0, $exception);
1388        }
1389    }
1390
1391    /**
1392     * Add any unit to a new value without overflowing current other unit given.
1393     *
1394     * @param string $valueUnit    unit name to modify
1395     * @param int    $value        amount to add to the input unit
1396     * @param string $overflowUnit unit name to not overflow
1397     *
1398     * @return static
1399     */
1400    public function addUnitNoOverflow($valueUnit, $value, $overflowUnit)
1401    {
1402        return $this->setUnitNoOverflow($valueUnit, $this->$valueUnit + $value, $overflowUnit);
1403    }
1404
1405    /**
1406     * Subtract any unit to a new value without overflowing current other unit given.
1407     *
1408     * @param string $valueUnit    unit name to modify
1409     * @param int    $value        amount to subtract to the input unit
1410     * @param string $overflowUnit unit name to not overflow
1411     *
1412     * @return static
1413     */
1414    public function subUnitNoOverflow($valueUnit, $value, $overflowUnit)
1415    {
1416        return $this->setUnitNoOverflow($valueUnit, $this->$valueUnit - $value, $overflowUnit);
1417    }
1418
1419    /**
1420     * Returns the minutes offset to UTC if no arguments passed, else set the timezone with given minutes shift passed.
1421     *
1422     * @param int|null $minuteOffset
1423     *
1424     * @return int|static
1425     */
1426    public function utcOffset(int $minuteOffset = null)
1427    {
1428        if (\func_num_args() < 1) {
1429            return $this->offsetMinutes;
1430        }
1431
1432        return $this->setTimezone(CarbonTimeZone::createFromMinuteOffset($minuteOffset));
1433    }
1434
1435    /**
1436     * Set the date with gregorian year, month and day numbers.
1437     *
1438     * @see https://php.net/manual/en/datetime.setdate.php
1439     *
1440     * @param int $year
1441     * @param int $month
1442     * @param int $day
1443     *
1444     * @return static
1445     */
1446    #[ReturnTypeWillChange]
1447    public function setDate($year, $month, $day)
1448    {
1449        return parent::setDate((int) $year, (int) $month, (int) $day);
1450    }
1451
1452    /**
1453     * Set a date according to the ISO 8601 standard - using weeks and day offsets rather than specific dates.
1454     *
1455     * @see https://php.net/manual/en/datetime.setisodate.php
1456     *
1457     * @param int $year
1458     * @param int $week
1459     * @param int $day
1460     *
1461     * @return static
1462     */
1463    #[ReturnTypeWillChange]
1464    public function setISODate($year, $week, $day = 1)
1465    {
1466        return parent::setISODate((int) $year, (int) $week, (int) $day);
1467    }
1468
1469    /**
1470     * Set the date and time all together.
1471     *
1472     * @param int $year
1473     * @param int $month
1474     * @param int $day
1475     * @param int $hour
1476     * @param int $minute
1477     * @param int $second
1478     * @param int $microseconds
1479     *
1480     * @return static
1481     */
1482    public function setDateTime($year, $month, $day, $hour, $minute, $second = 0, $microseconds = 0)
1483    {
1484        return $this->setDate($year, $month, $day)->setTime((int) $hour, (int) $minute, (int) $second, (int) $microseconds);
1485    }
1486
1487    /**
1488     * Resets the current time of the DateTime object to a different time.
1489     *
1490     * @see https://php.net/manual/en/datetime.settime.php
1491     *
1492     * @param int $hour
1493     * @param int $minute
1494     * @param int $second
1495     * @param int $microseconds
1496     *
1497     * @return static
1498     */
1499    #[ReturnTypeWillChange]
1500    public function setTime($hour, $minute, $second = 0, $microseconds = 0)
1501    {
1502        return parent::setTime((int) $hour, (int) $minute, (int) $second, (int) $microseconds);
1503    }
1504
1505    /**
1506     * Set the instance's timestamp.
1507     *
1508     * Timestamp input can be given as int, float or a string containing one or more numbers.
1509     *
1510     * @param float|int|string $unixTimestamp
1511     *
1512     * @return static
1513     */
1514    #[ReturnTypeWillChange]
1515    public function setTimestamp($unixTimestamp)
1516    {
1517        [$timestamp, $microseconds] = self::getIntegerAndDecimalParts($unixTimestamp);
1518
1519        return parent::setTimestamp((int) $timestamp)->setMicroseconds((int) $microseconds);
1520    }
1521
1522    /**
1523     * Set the time by time string.
1524     *
1525     * @param string $time
1526     *
1527     * @return static
1528     */
1529    public function setTimeFromTimeString($time)
1530    {
1531        if (!str_contains($time, ':')) {
1532            $time .= ':0';
1533        }
1534
1535        return $this->modify($time);
1536    }
1537
1538    /**
1539     * @alias setTimezone
1540     *
1541     * @param DateTimeZone|string $value
1542     *
1543     * @return static
1544     */
1545    public function timezone($value)
1546    {
1547        return $this->setTimezone($value);
1548    }
1549
1550    /**
1551     * Set the timezone or returns the timezone name if no arguments passed.
1552     *
1553     * @param DateTimeZone|string $value
1554     *
1555     * @return static|string
1556     */
1557    public function tz($value = null)
1558    {
1559        if (\func_num_args() < 1) {
1560            return $this->tzName;
1561        }
1562
1563        return $this->setTimezone($value);
1564    }
1565
1566    /**
1567     * Set the instance's timezone from a string or object.
1568     *
1569     * @param DateTimeZone|string $value
1570     *
1571     * @return static
1572     */
1573    #[ReturnTypeWillChange]
1574    public function setTimezone($value)
1575    {
1576        $tz = static::safeCreateDateTimeZone($value);
1577
1578        if ($tz === false && !self::isStrictModeEnabled()) {
1579            $tz = new CarbonTimeZone();
1580        }
1581
1582        return parent::setTimezone($tz);
1583    }
1584
1585    /**
1586     * Set the instance's timezone from a string or object and add/subtract the offset difference.
1587     *
1588     * @param DateTimeZone|string $value
1589     *
1590     * @return static
1591     */
1592    public function shiftTimezone($value)
1593    {
1594        $dateTimeString = $this->format('Y-m-d H:i:s.u');
1595
1596        return $this
1597            ->setTimezone($value)
1598            ->modify($dateTimeString);
1599    }
1600
1601    /**
1602     * Set the instance's timezone to UTC.
1603     *
1604     * @return static
1605     */
1606    public function utc()
1607    {
1608        return $this->setTimezone('UTC');
1609    }
1610
1611    /**
1612     * Set the year, month, and date for this instance to that of the passed instance.
1613     *
1614     * @param Carbon|DateTimeInterface $date now if null
1615     *
1616     * @return static
1617     */
1618    public function setDateFrom($date = null)
1619    {
1620        $date = $this->resolveCarbon($date);
1621
1622        return $this->setDate($date->year, $date->month, $date->day);
1623    }
1624
1625    /**
1626     * Set the hour, minute, second and microseconds for this instance to that of the passed instance.
1627     *
1628     * @param Carbon|DateTimeInterface $date now if null
1629     *
1630     * @return static
1631     */
1632    public function setTimeFrom($date = null)
1633    {
1634        $date = $this->resolveCarbon($date);
1635
1636        return $this->setTime($date->hour, $date->minute, $date->second, $date->microsecond);
1637    }
1638
1639    /**
1640     * Set the date and time for this instance to that of the passed instance.
1641     *
1642     * @param Carbon|DateTimeInterface $date
1643     *
1644     * @return static
1645     */
1646    public function setDateTimeFrom($date = null)
1647    {
1648        $date = $this->resolveCarbon($date);
1649
1650        return $this->modify($date->rawFormat('Y-m-d H:i:s.u'));
1651    }
1652
1653    /**
1654     * Get the days of the week
1655     *
1656     * @return array
1657     */
1658    public static function getDays()
1659    {
1660        return static::$days;
1661    }
1662
1663    ///////////////////////////////////////////////////////////////////
1664    /////////////////////// WEEK SPECIAL DAYS /////////////////////////
1665    ///////////////////////////////////////////////////////////////////
1666
1667    private static function getFirstDayOfWeek(): int
1668    {
1669        return (int) static::getTranslationMessageWith(
1670            static::getTranslator(),
1671            'first_day_of_week'
1672        );
1673    }
1674
1675    /**
1676     * Get the first day of week
1677     *
1678     * @return int
1679     */
1680    public static function getWeekStartsAt()
1681    {
1682        if (static::$weekStartsAt === static::WEEK_DAY_AUTO) {
1683            return static::getFirstDayOfWeek();
1684        }
1685
1686        return static::$weekStartsAt;
1687    }
1688
1689    /**
1690     * @deprecated To avoid conflict between different third-party libraries, static setters should not be used.
1691     *             Use $weekEndsAt optional parameter instead when using endOfWeek method. You can also use the
1692     *             'first_day_of_week' locale setting to change the start of week according to current locale
1693     *             selected and implicitly the end of week.
1694     *
1695     * Set the first day of week
1696     *
1697     * @param int|string $day week start day (or 'auto' to get the first day of week from Carbon::getLocale() culture).
1698     *
1699     * @return void
1700     */
1701    public static function setWeekStartsAt($day)
1702    {
1703        static::$weekStartsAt = $day === static::WEEK_DAY_AUTO ? $day : max(0, (7 + $day) % 7);
1704    }
1705
1706    /**
1707     * Get the last day of week
1708     *
1709     * @return int
1710     */
1711    public static function getWeekEndsAt()
1712    {
1713        if (static::$weekStartsAt === static::WEEK_DAY_AUTO) {
1714            return (int) (static::DAYS_PER_WEEK - 1 + static::getFirstDayOfWeek()) % static::DAYS_PER_WEEK;
1715        }
1716
1717        return static::$weekEndsAt;
1718    }
1719
1720    /**
1721     * @deprecated To avoid conflict between different third-party libraries, static setters should not be used.
1722     *             Use $weekStartsAt optional parameter instead when using startOfWeek, floorWeek, ceilWeek
1723     *             or roundWeek method. You can also use the 'first_day_of_week' locale setting to change the
1724     *             start of week according to current locale selected and implicitly the end of week.
1725     *
1726     * Set the last day of week
1727     *
1728     * @param int|string $day week end day (or 'auto' to get the day before the first day of week
1729     *                        from Carbon::getLocale() culture).
1730     *
1731     * @return void
1732     */
1733    public static function setWeekEndsAt($day)
1734    {
1735        static::$weekEndsAt = $day === static::WEEK_DAY_AUTO ? $day : max(0, (7 + $day) % 7);
1736    }
1737
1738    /**
1739     * Get weekend days
1740     *
1741     * @return array
1742     */
1743    public static function getWeekendDays()
1744    {
1745        return static::$weekendDays;
1746    }
1747
1748    /**
1749     * @deprecated To avoid conflict between different third-party libraries, static setters should not be used.
1750     *             You should rather consider week-end is always saturday and sunday, and if you have some custom
1751     *             week-end days to handle, give to those days an other name and create a macro for them:
1752     *
1753     *             ```
1754     *             Carbon::macro('isDayOff', function ($date) {
1755     *                 return $date->isSunday() || $date->isMonday();
1756     *             });
1757     *             Carbon::macro('isNotDayOff', function ($date) {
1758     *                 return !$date->isDayOff();
1759     *             });
1760     *             if ($someDate->isDayOff()) ...
1761     *             if ($someDate->isNotDayOff()) ...
1762     *             // Add 5 not-off days
1763     *             $count = 5;
1764     *             while ($someDate->isDayOff() || ($count-- > 0)) {
1765     *                 $someDate->addDay();
1766     *             }
1767     *             ```
1768     *
1769     * Set weekend days
1770     *
1771     * @param array $days
1772     *
1773     * @return void
1774     */
1775    public static function setWeekendDays($days)
1776    {
1777        static::$weekendDays = $days;
1778    }
1779
1780    /**
1781     * Determine if a time string will produce a relative date.
1782     *
1783     * @param string $time
1784     *
1785     * @return bool true if time match a relative date, false if absolute or invalid time string
1786     */
1787    public static function hasRelativeKeywords($time)
1788    {
1789        if (!$time || strtotime($time) === false) {
1790            return false;
1791        }
1792
1793        $date1 = new DateTime('2000-01-01T00:00:00Z');
1794        $date1->modify($time);
1795        $date2 = new DateTime('2001-12-25T00:00:00Z');
1796        $date2->modify($time);
1797
1798        return $date1 != $date2;
1799    }
1800
1801    ///////////////////////////////////////////////////////////////////
1802    /////////////////////// STRING FORMATTING /////////////////////////
1803    ///////////////////////////////////////////////////////////////////
1804
1805    /**
1806     * @deprecated To avoid conflict between different third-party libraries, static setters should not be used.
1807     *             You should rather use UTF-8 language packages on every machine.
1808     *
1809     * Set if UTF8 will be used for localized date/time.
1810     *
1811     * @param bool $utf8
1812     */
1813    public static function setUtf8($utf8)
1814    {
1815        static::$utf8 = $utf8;
1816    }
1817
1818    /**
1819     * Format the instance with the current locale.  You can set the current
1820     * locale using setlocale() https://php.net/setlocale.
1821     *
1822     * @param string $format
1823     *
1824     * @return string
1825     */
1826    public function formatLocalized($format)
1827    {
1828        // Check for Windows to find and replace the %e modifier correctly.
1829        if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
1830            $format = preg_replace('#(?<!%)((?:%%)*)%e#', '\1%#d', $format); // @codeCoverageIgnore
1831        }
1832
1833        $formatted = strftime($format, strtotime($this->toDateTimeString()));
1834
1835        return static::$utf8 ? utf8_encode($formatted) : $formatted;
1836    }
1837
1838    /**
1839     * Returns list of locale formats for ISO formatting.
1840     *
1841     * @param string|null $locale current locale used if null
1842     *
1843     * @return array
1844     */
1845    public function getIsoFormats($locale = null)
1846    {
1847        return [
1848            'LT' => $this->getTranslationMessage('formats.LT', $locale, 'h:mm A'),
1849            'LTS' => $this->getTranslationMessage('formats.LTS', $locale, 'h:mm:ss A'),
1850            'L' => $this->getTranslationMessage('formats.L', $locale, 'MM/DD/YYYY'),
1851            'LL' => $this->getTranslationMessage('formats.LL', $locale, 'MMMM D, YYYY'),
1852            'LLL' => $this->getTranslationMessage('formats.LLL', $locale, 'MMMM D, YYYY h:mm A'),
1853            'LLLL' => $this->getTranslationMessage('formats.LLLL', $locale, 'dddd, MMMM D, YYYY h:mm A'),
1854        ];
1855    }
1856
1857    /**
1858     * Returns list of calendar formats for ISO formatting.
1859     *
1860     * @param string|null $locale current locale used if null
1861     *
1862     * @return array
1863     */
1864    public function getCalendarFormats($locale = null)
1865    {
1866        return [
1867            'sameDay' => $this->getTranslationMessage('calendar.sameDay', $locale, '[Today at] LT'),
1868            'nextDay' => $this->getTranslationMessage('calendar.nextDay', $locale, '[Tomorrow at] LT'),
1869            'nextWeek' => $this->getTranslationMessage('calendar.nextWeek', $locale, 'dddd [at] LT'),
1870            'lastDay' => $this->getTranslationMessage('calendar.lastDay', $locale, '[Yesterday at] LT'),
1871            'lastWeek' => $this->getTranslationMessage('calendar.lastWeek', $locale, '[Last] dddd [at] LT'),
1872            'sameElse' => $this->getTranslationMessage('calendar.sameElse', $locale, 'L'),
1873        ];
1874    }
1875
1876    /**
1877     * Returns list of locale units for ISO formatting.
1878     *
1879     * @return array
1880     */
1881    public static function getIsoUnits()
1882    {
1883        static $units = null;
1884
1885        if ($units === null) {
1886            $units = [
1887                'OD' => ['getAltNumber', ['day']],
1888                'OM' => ['getAltNumber', ['month']],
1889                'OY' => ['getAltNumber', ['year']],
1890                'OH' => ['getAltNumber', ['hour']],
1891                'Oh' => ['getAltNumber', ['h']],
1892                'Om' => ['getAltNumber', ['minute']],
1893                'Os' => ['getAltNumber', ['second']],
1894                'D' => 'day',
1895                'DD' => ['rawFormat', ['d']],
1896                'Do' => ['ordinal', ['day', 'D']],
1897                'd' => 'dayOfWeek',
1898                'dd' => function (CarbonInterface $date, $originalFormat = null) {
1899                    return $date->getTranslatedMinDayName($originalFormat);
1900                },
1901                'ddd' => function (CarbonInterface $date, $originalFormat = null) {
1902                    return $date->getTranslatedShortDayName($originalFormat);
1903                },
1904                'dddd' => function (CarbonInterface $date, $originalFormat = null) {
1905                    return $date->getTranslatedDayName($originalFormat);
1906                },
1907                'DDD' => 'dayOfYear',
1908                'DDDD' => ['getPaddedUnit', ['dayOfYear', 3]],
1909                'DDDo' => ['ordinal', ['dayOfYear', 'DDD']],
1910                'e' => ['weekday', []],
1911                'E' => 'dayOfWeekIso',
1912                'H' => ['rawFormat', ['G']],
1913                'HH' => ['rawFormat', ['H']],
1914                'h' => ['rawFormat', ['g']],
1915                'hh' => ['rawFormat', ['h']],
1916                'k' => 'noZeroHour',
1917                'kk' => ['getPaddedUnit', ['noZeroHour']],
1918                'hmm' => ['rawFormat', ['gi']],
1919                'hmmss' => ['rawFormat', ['gis']],
1920                'Hmm' => ['rawFormat', ['Gi']],
1921                'Hmmss' => ['rawFormat', ['Gis']],
1922                'm' => 'minute',
1923                'mm' => ['rawFormat', ['i']],
1924                'a' => 'meridiem',
1925                'A' => 'upperMeridiem',
1926                's' => 'second',
1927                'ss' => ['getPaddedUnit', ['second']],
1928                'S' => function (CarbonInterface $date) {
1929                    return (string) floor($date->micro / 100000);
1930                },
1931                'SS' => function (CarbonInterface $date) {
1932                    return str_pad((string) floor($date->micro / 10000), 2, '0', STR_PAD_LEFT);
1933                },
1934                'SSS' => function (CarbonInterface $date) {
1935                    return str_pad((string) floor($date->micro / 1000), 3, '0', STR_PAD_LEFT);
1936                },
1937                'SSSS' => function (CarbonInterface $date) {
1938                    return str_pad((string) floor($date->micro / 100), 4, '0', STR_PAD_LEFT);
1939                },
1940                'SSSSS' => function (CarbonInterface $date) {
1941                    return str_pad((string) floor($date->micro / 10), 5, '0', STR_PAD_LEFT);
1942                },
1943                'SSSSSS' => ['getPaddedUnit', ['micro', 6]],
1944                'SSSSSSS' => function (CarbonInterface $date) {
1945                    return str_pad((string) floor($date->micro * 10), 7, '0', STR_PAD_LEFT);
1946                },
1947                'SSSSSSSS' => function (CarbonInterface $date) {
1948                    return str_pad((string) floor($date->micro * 100), 8, '0', STR_PAD_LEFT);
1949                },
1950                'SSSSSSSSS' => function (CarbonInterface $date) {
1951                    return str_pad((string) floor($date->micro * 1000), 9, '0', STR_PAD_LEFT);
1952                },
1953                'M' => 'month',
1954                'MM' => ['rawFormat', ['m']],
1955                'MMM' => function (CarbonInterface $date, $originalFormat = null) {
1956                    $month = $date->getTranslatedShortMonthName($originalFormat);
1957                    $suffix = $date->getTranslationMessage('mmm_suffix');
1958                    if ($suffix && $month !== $date->monthName) {
1959                        $month .= $suffix;
1960                    }
1961
1962                    return $month;
1963                },
1964                'MMMM' => function (CarbonInterface $date, $originalFormat = null) {
1965                    return $date->getTranslatedMonthName($originalFormat);
1966                },
1967                'Mo' => ['ordinal', ['month', 'M']],
1968                'Q' => 'quarter',
1969                'Qo' => ['ordinal', ['quarter', 'M']],
1970                'G' => 'isoWeekYear',
1971                'GG' => ['getPaddedUnit', ['isoWeekYear']],
1972                'GGG' => ['getPaddedUnit', ['isoWeekYear', 3]],
1973                'GGGG' => ['getPaddedUnit', ['isoWeekYear', 4]],
1974                'GGGGG' => ['getPaddedUnit', ['isoWeekYear', 5]],
1975                'g' => 'weekYear',
1976                'gg' => ['getPaddedUnit', ['weekYear']],
1977                'ggg' => ['getPaddedUnit', ['weekYear', 3]],
1978                'gggg' => ['getPaddedUnit', ['weekYear', 4]],
1979                'ggggg' => ['getPaddedUnit', ['weekYear', 5]],
1980                'W' => 'isoWeek',
1981                'WW' => ['getPaddedUnit', ['isoWeek']],
1982                'Wo' => ['ordinal', ['isoWeek', 'W']],
1983                'w' => 'week',
1984                'ww' => ['getPaddedUnit', ['week']],
1985                'wo' => ['ordinal', ['week', 'w']],
1986                'x' => ['valueOf', []],
1987                'X' => 'timestamp',
1988                'Y' => 'year',
1989                'YY' => ['rawFormat', ['y']],
1990                'YYYY' => ['getPaddedUnit', ['year', 4]],
1991                'YYYYY' => ['getPaddedUnit', ['year', 5]],
1992                'YYYYYY' => function (CarbonInterface $date) {
1993                    return ($date->year < 0 ? '' : '+').$date->getPaddedUnit('year', 6);
1994                },
1995                'z' => ['rawFormat', ['T']],
1996                'zz' => 'tzName',
1997                'Z' => ['getOffsetString', []],
1998                'ZZ' => ['getOffsetString', ['']],
1999            ];
2000        }
2001
2002        return $units;
2003    }
2004
2005    /**
2006     * Returns a unit of the instance padded with 0 by default or any other string if specified.
2007     *
2008     * @param string $unit      Carbon unit name
2009     * @param int    $length    Length of the output (2 by default)
2010     * @param string $padString String to use for padding ("0" by default)
2011     * @param int    $padType   Side(s) to pad (STR_PAD_LEFT by default)
2012     *
2013     * @return string
2014     */
2015    public function getPaddedUnit($unit, $length = 2, $padString = '0', $padType = STR_PAD_LEFT)
2016    {
2017        return ($this->$unit < 0 ? '-' : '').str_pad((string) abs($this->$unit), $length, $padString, $padType);
2018    }
2019
2020    /**
2021     * Return a property with its ordinal.
2022     *
2023     * @param string      $key
2024     * @param string|null $period
2025     *
2026     * @return string
2027     */
2028    public function ordinal(string $key, ?string $period = null): string
2029    {
2030        $number = $this->$key;
2031        $result = $this->translate('ordinal', [
2032            ':number' => $number,
2033            ':period' => (string) $period,
2034        ]);
2035
2036        return (string) ($result === 'ordinal' ? $number : $result);
2037    }
2038
2039    /**
2040     * Return the meridiem of the current time in the current locale.
2041     *
2042     * @param bool $isLower if true, returns lowercase variant if available in the current locale.
2043     *
2044     * @return string
2045     */
2046    public function meridiem(bool $isLower = false): string
2047    {
2048        $hour = $this->hour;
2049        $index = $hour < 12 ? 0 : 1;
2050
2051        if ($isLower) {
2052            $key = 'meridiem.'.($index + 2);
2053            $result = $this->translate($key);
2054
2055            if ($result !== $key) {
2056                return $result;
2057            }
2058        }
2059
2060        $key = "meridiem.$index";
2061        $result = $this->translate($key);
2062        if ($result === $key) {
2063            $result = $this->translate('meridiem', [
2064                ':hour' => $this->hour,
2065                ':minute' => $this->minute,
2066                ':isLower' => $isLower,
2067            ]);
2068
2069            if ($result === 'meridiem') {
2070                return $isLower ? $this->latinMeridiem : $this->latinUpperMeridiem;
2071            }
2072        } elseif ($isLower) {
2073            $result = mb_strtolower($result);
2074        }
2075
2076        return $result;
2077    }
2078
2079    /**
2080     * Returns the alternative number for a given date property if available in the current locale.
2081     *
2082     * @param string $key date property
2083     *
2084     * @return string
2085     */
2086    public function getAltNumber(string $key): string
2087    {
2088        return $this->translateNumber(\strlen($key) > 1 ? $this->$key : $this->rawFormat('h'));
2089    }
2090
2091    /**
2092     * Format in the current language using ISO replacement patterns.
2093     *
2094     * @param string      $format
2095     * @param string|null $originalFormat provide context if a chunk has been passed alone
2096     *
2097     * @return string
2098     */
2099    public function isoFormat(string $format, ?string $originalFormat = null): string
2100    {
2101        $result = '';
2102        $length = mb_strlen($format);
2103        $originalFormat = $originalFormat ?: $format;
2104        $inEscaped = false;
2105        $formats = null;
2106        $units = null;
2107
2108        for ($i = 0; $i < $length; $i++) {
2109            $char = mb_substr($format, $i, 1);
2110
2111            if ($char === '\\') {
2112                $result .= mb_substr($format, ++$i, 1);
2113
2114                continue;
2115            }
2116
2117            if ($char === '[' && !$inEscaped) {
2118                $inEscaped = true;
2119
2120                continue;
2121            }
2122
2123            if ($char === ']' && $inEscaped) {
2124                $inEscaped = false;
2125
2126                continue;
2127            }
2128
2129            if ($inEscaped) {
2130                $result .= $char;
2131
2132                continue;
2133            }
2134
2135            $input = mb_substr($format, $i);
2136
2137            if (preg_match('/^(LTS|LT|[Ll]{1,4})/', $input, $match)) {
2138                if ($formats === null) {
2139                    $formats = $this->getIsoFormats();
2140                }
2141
2142                $code = $match[0];
2143                $sequence = $formats[$code] ?? preg_replace_callback(
2144                    '/MMMM|MM|DD|dddd/',
2145                    function ($code) {
2146                        return mb_substr($code[0], 1);
2147                    },
2148                    $formats[strtoupper($code)] ?? ''
2149                );
2150                $rest = mb_substr($format, $i + mb_strlen($code));
2151                $format = mb_substr($format, 0, $i).$sequence.$rest;
2152                $length = mb_strlen($format);
2153                $input = $sequence.$rest;
2154            }
2155
2156            if (preg_match('/^'.CarbonInterface::ISO_FORMAT_REGEXP.'/', $input, $match)) {
2157                $code = $match[0];
2158
2159                if ($units === null) {
2160                    $units = static::getIsoUnits();
2161                }
2162
2163                $sequence = $units[$code] ?? '';
2164
2165                if ($sequence instanceof Closure) {
2166                    $sequence = $sequence($this, $originalFormat);
2167                } elseif (\is_array($sequence)) {
2168                    try {
2169                        $sequence = $this->{$sequence[0]}(...$sequence[1]);
2170                    } catch (ReflectionException | InvalidArgumentException | BadMethodCallException $e) {
2171                        $sequence = '';
2172                    }
2173                } elseif (\is_string($sequence)) {
2174                    $sequence = $this->$sequence ?? $code;
2175                }
2176
2177                $format = mb_substr($format, 0, $i).$sequence.mb_substr($format, $i + mb_strlen($code));
2178                $i += mb_strlen((string) $sequence) - 1;
2179                $length = mb_strlen($format);
2180                $char = $sequence;
2181            }
2182
2183            $result .= $char;
2184        }
2185
2186        return $result;
2187    }
2188
2189    /**
2190     * List of replacements from date() format to isoFormat().
2191     *
2192     * @return array
2193     */
2194    public static function getFormatsToIsoReplacements()
2195    {
2196        static $replacements = null;
2197
2198        if ($replacements === null) {
2199            $replacements = [
2200                'd' => true,
2201                'D' => 'ddd',
2202                'j' => true,
2203                'l' => 'dddd',
2204                'N' => true,
2205                'S' => function ($date) {
2206                    $day = $date->rawFormat('j');
2207
2208                    return str_replace((string) $day, '', $date->isoFormat('Do'));
2209                },
2210                'w' => true,
2211                'z' => true,
2212                'W' => true,
2213                'F' => 'MMMM',
2214                'm' => true,
2215                'M' => 'MMM',
2216                'n' => true,
2217                't' => true,
2218                'L' => true,
2219                'o' => true,
2220                'Y' => true,
2221                'y' => true,
2222                'a' => 'a',
2223                'A' => 'A',
2224                'B' => true,
2225                'g' => true,
2226                'G' => true,
2227                'h' => true,
2228                'H' => true,
2229                'i' => true,
2230                's' => true,
2231                'u' => true,
2232                'v' => true,
2233                'E' => true,
2234                'I' => true,
2235                'O' => true,
2236                'P' => true,
2237                'Z' => true,
2238                'c' => true,
2239                'r' => true,
2240                'U' => true,
2241            ];
2242        }
2243
2244        return $replacements;
2245    }
2246
2247    /**
2248     * Format as ->format() do (using date replacements patterns from https://php.net/manual/en/function.date.php)
2249     * but translate words whenever possible (months, day names, etc.) using the current locale.
2250     *
2251     * @param string $format
2252     *
2253     * @return string
2254     */
2255    public function translatedFormat(string $format): string
2256    {
2257        $replacements = static::getFormatsToIsoReplacements();
2258        $context = '';
2259        $isoFormat = '';
2260        $length = mb_strlen($format);
2261
2262        for ($i = 0; $i < $length; $i++) {
2263            $char = mb_substr($format, $i, 1);
2264
2265            if ($char === '\\') {
2266                $replacement = mb_substr($format, $i, 2);
2267                $isoFormat .= $replacement;
2268                $i++;
2269
2270                continue;
2271            }
2272
2273            if (!isset($replacements[$char])) {
2274                $replacement = preg_match('/^[A-Za-z]$/', $char) ? "\\$char" : $char;
2275                $isoFormat .= $replacement;
2276                $context .= $replacement;
2277
2278                continue;
2279            }
2280
2281            $replacement = $replacements[$char];
2282
2283            if ($replacement === true) {
2284                static $contextReplacements = null;
2285
2286                if ($contextReplacements === null) {
2287                    $contextReplacements = [
2288                        'm' => 'MM',
2289                        'd' => 'DD',
2290                        't' => 'D',
2291                        'j' => 'D',
2292                        'N' => 'e',
2293                        'w' => 'e',
2294                        'n' => 'M',
2295                        'o' => 'YYYY',
2296                        'Y' => 'YYYY',
2297                        'y' => 'YY',
2298                        'g' => 'h',
2299                        'G' => 'H',
2300                        'h' => 'hh',
2301                        'H' => 'HH',
2302                        'i' => 'mm',
2303                        's' => 'ss',
2304                    ];
2305                }
2306
2307                $isoFormat .= '['.$this->rawFormat($char).']';
2308                $context .= $contextReplacements[$char] ?? ' ';
2309
2310                continue;
2311            }
2312
2313            if ($replacement instanceof Closure) {
2314                $replacement = '['.$replacement($this).']';
2315                $isoFormat .= $replacement;
2316                $context .= $replacement;
2317
2318                continue;
2319            }
2320
2321            $isoFormat .= $replacement;
2322            $context .= $replacement;
2323        }
2324
2325        return $this->isoFormat($isoFormat, $context);
2326    }
2327
2328    /**
2329     * Returns the offset hour and minute formatted with +/- and a given separator (":" by default).
2330     * For example, if the time zone is 9 hours 30 minutes, you'll get "+09:30", with "@@" as first
2331     * argument, "+09@@30", with "" as first argument, "+0930". Negative offset will return something
2332     * like "-12:00".
2333     *
2334     * @param string $separator string to place between hours and minutes (":" by default)
2335     *
2336     * @return string
2337     */
2338    public function getOffsetString($separator = ':')
2339    {
2340        $second = $this->getOffset();
2341        $symbol = $second < 0 ? '-' : '+';
2342        $minute = abs($second) / static::SECONDS_PER_MINUTE;
2343        $hour = str_pad((string) floor($minute / static::MINUTES_PER_HOUR), 2, '0', STR_PAD_LEFT);
2344        $minute = str_pad((string) ($minute % static::MINUTES_PER_HOUR), 2, '0', STR_PAD_LEFT);
2345
2346        return "$symbol$hour$separator$minute";
2347    }
2348
2349    protected static function executeStaticCallable($macro, ...$parameters)
2350    {
2351        return static::bindMacroContext(null, function () use (&$macro, &$parameters) {
2352            if ($macro instanceof Closure) {
2353                $boundMacro = @Closure::bind($macro, null, static::class);
2354
2355                return ($boundMacro ?: $macro)(...$parameters);
2356            }
2357
2358            return $macro(...$parameters);
2359        });
2360    }
2361
2362    /**
2363     * Dynamically handle calls to the class.
2364     *
2365     * @param string $method     magic method name called
2366     * @param array  $parameters parameters list
2367     *
2368     * @throws BadMethodCallException
2369     *
2370     * @return mixed
2371     */
2372    public static function __callStatic($method, $parameters)
2373    {
2374        if (!static::hasMacro($method)) {
2375            foreach (static::getGenericMacros() as $callback) {
2376                try {
2377                    return static::executeStaticCallable($callback, $method, ...$parameters);
2378                } catch (BadMethodCallException $exception) {
2379                    continue;
2380                }
2381            }
2382            if (static::isStrictModeEnabled()) {
2383                throw new UnknownMethodException(sprintf('%s::%s', static::class, $method));
2384            }
2385
2386            return null;
2387        }
2388
2389        return static::executeStaticCallable(static::$globalMacros[$method], ...$parameters);
2390    }
2391
2392    /**
2393     * Set specified unit to new given value.
2394     *
2395     * @param string $unit  year, month, day, hour, minute, second or microsecond
2396     * @param int    $value new value for given unit
2397     *
2398     * @return static
2399     */
2400    public function setUnit($unit, $value = null)
2401    {
2402        $unit = static::singularUnit($unit);
2403        $dateUnits = ['year', 'month', 'day'];
2404        if (\in_array($unit, $dateUnits)) {
2405            return $this->setDate(...array_map(function ($name) use ($unit, $value) {
2406                return (int) ($name === $unit ? $value : $this->$name);
2407            }, $dateUnits));
2408        }
2409
2410        $units = ['hour', 'minute', 'second', 'micro'];
2411        if ($unit === 'millisecond' || $unit === 'milli') {
2412            $value *= 1000;
2413            $unit = 'micro';
2414        } elseif ($unit === 'microsecond') {
2415            $unit = 'micro';
2416        }
2417
2418        return $this->setTime(...array_map(function ($name) use ($unit, $value) {
2419            return (int) ($name === $unit ? $value : $this->$name);
2420        }, $units));
2421    }
2422
2423    /**
2424     * Returns standardized singular of a given singular/plural unit name (in English).
2425     *
2426     * @param string $unit
2427     *
2428     * @return string
2429     */
2430    public static function singularUnit(string $unit): string
2431    {
2432        $unit = rtrim(mb_strtolower($unit), 's');
2433
2434        if ($unit === 'centurie') {
2435            return 'century';
2436        }
2437
2438        if ($unit === 'millennia') {
2439            return 'millennium';
2440        }
2441
2442        return $unit;
2443    }
2444
2445    /**
2446     * Returns standardized plural of a given singular/plural unit name (in English).
2447     *
2448     * @param string $unit
2449     *
2450     * @return string
2451     */
2452    public static function pluralUnit(string $unit): string
2453    {
2454        $unit = rtrim(strtolower($unit), 's');
2455
2456        if ($unit === 'century') {
2457            return 'centuries';
2458        }
2459
2460        if ($unit === 'millennium' || $unit === 'millennia') {
2461            return 'millennia';
2462        }
2463
2464        return "${unit}s";
2465    }
2466
2467    protected function executeCallable($macro, ...$parameters)
2468    {
2469        if ($macro instanceof Closure) {
2470            $boundMacro = @$macro->bindTo($this, static::class) ?: @$macro->bindTo(null, static::class);
2471
2472            return ($boundMacro ?: $macro)(...$parameters);
2473        }
2474
2475        return $macro(...$parameters);
2476    }
2477
2478    protected function executeCallableWithContext($macro, ...$parameters)
2479    {
2480        return static::bindMacroContext($this, function () use (&$macro, &$parameters) {
2481            return $this->executeCallable($macro, ...$parameters);
2482        });
2483    }
2484
2485    protected static function getGenericMacros()
2486    {
2487        foreach (static::$globalGenericMacros as $list) {
2488            foreach ($list as $macro) {
2489                yield $macro;
2490            }
2491        }
2492    }
2493
2494    /**
2495     * Dynamically handle calls to the class.
2496     *
2497     * @param string $method     magic method name called
2498     * @param array  $parameters parameters list
2499     *
2500     * @throws UnknownMethodException|BadMethodCallException|ReflectionException|Throwable
2501     *
2502     * @return mixed
2503     */
2504    public function __call($method, $parameters)
2505    {
2506        $diffSizes = [
2507            // @mode diffForHumans
2508            'short' => true,
2509            // @mode diffForHumans
2510            'long' => false,
2511        ];
2512        $diffSyntaxModes = [
2513            // @call diffForHumans
2514            'Absolute' => CarbonInterface::DIFF_ABSOLUTE,
2515            // @call diffForHumans
2516            'Relative' => CarbonInterface::DIFF_RELATIVE_AUTO,
2517            // @call diffForHumans
2518            'RelativeToNow' => CarbonInterface::DIFF_RELATIVE_TO_NOW,
2519            // @call diffForHumans
2520            'RelativeToOther' => CarbonInterface::DIFF_RELATIVE_TO_OTHER,
2521        ];
2522        $sizePattern = implode('|', array_keys($diffSizes));
2523        $syntaxPattern = implode('|', array_keys($diffSyntaxModes));
2524
2525        if (preg_match("/^(?<size>$sizePattern)(?<syntax>$syntaxPattern)DiffForHumans$/", $method, $match)) {
2526            $dates = array_filter($parameters, function ($parameter) {
2527                return $parameter instanceof DateTimeInterface;
2528            });
2529            $other = null;
2530
2531            if (\count($dates)) {
2532                $key = key($dates);
2533                $other = current($dates);
2534                array_splice($parameters, $key, 1);
2535            }
2536
2537            return $this->diffForHumans($other, $diffSyntaxModes[$match['syntax']], $diffSizes[$match['size']], ...$parameters);
2538        }
2539
2540        $roundedValue = $this->callRoundMethod($method, $parameters);
2541
2542        if ($roundedValue !== null) {
2543            return $roundedValue;
2544        }
2545
2546        $unit = rtrim($method, 's');
2547
2548        if (str_starts_with($unit, 'is')) {
2549            $word = substr($unit, 2);
2550
2551            if (\in_array($word, static::$days)) {
2552                return $this->isDayOfWeek($word);
2553            }
2554
2555            switch ($word) {
2556                // @call is Check if the current instance has UTC timezone. (Both isUtc and isUTC cases are valid.)
2557                case 'Utc':
2558                case 'UTC':
2559                    return $this->utc;
2560                // @call is Check if the current instance has non-UTC timezone.
2561                case 'Local':
2562                    return $this->local;
2563                // @call is Check if the current instance is a valid date.
2564                case 'Valid':
2565                    return $this->year !== 0;
2566                // @call is Check if the current instance is in a daylight saving time.
2567                case 'DST':
2568                    return $this->dst;
2569            }
2570        }
2571
2572        $action = substr($unit, 0, 3);
2573        $overflow = null;
2574
2575        if ($action === 'set') {
2576            $unit = strtolower(substr($unit, 3));
2577        }
2578
2579        if (\in_array($unit, static::$units)) {
2580            return $this->setUnit($unit, ...$parameters);
2581        }
2582
2583        if ($action === 'add' || $action === 'sub') {
2584            $unit = substr($unit, 3);
2585
2586            if (str_starts_with($unit, 'Real')) {
2587                $unit = static::singularUnit(substr($unit, 4));
2588
2589                return $this->{"${action}RealUnit"}($unit, ...$parameters);
2590            }
2591
2592            if (preg_match('/^(Month|Quarter|Year|Decade|Century|Centurie|Millennium|Millennia)s?(No|With|Without|WithNo)Overflow$/', $unit, $match)) {
2593                $unit = $match[1];
2594                $overflow = $match[2] === 'With';
2595            }
2596
2597            $unit = static::singularUnit($unit);
2598        }
2599
2600        if (static::isModifiableUnit($unit)) {
2601            return $this->{"${action}Unit"}($unit, $parameters[0] ?? 1, $overflow);
2602        }
2603
2604        $sixFirstLetters = substr($unit, 0, 6);
2605        $factor = -1;
2606
2607        if ($sixFirstLetters === 'isLast') {
2608            $sixFirstLetters = 'isNext';
2609            $factor = 1;
2610        }
2611
2612        if ($sixFirstLetters === 'isNext') {
2613            $lowerUnit = strtolower(substr($unit, 6));
2614
2615            if (static::isModifiableUnit($lowerUnit)) {
2616                return $this->copy()->addUnit($lowerUnit, $factor, false)->isSameUnit($lowerUnit, ...$parameters);
2617            }
2618        }
2619
2620        if ($sixFirstLetters === 'isSame') {
2621            try {
2622                return $this->isSameUnit(strtolower(substr($unit, 6)), ...$parameters);
2623            } catch (BadComparisonUnitException $exception) {
2624                // Try next
2625            }
2626        }
2627
2628        if (str_starts_with($unit, 'isCurrent')) {
2629            try {
2630                return $this->isCurrentUnit(strtolower(substr($unit, 9)));
2631            } catch (BadComparisonUnitException | BadMethodCallException $exception) {
2632                // Try next
2633            }
2634        }
2635
2636        if (str_ends_with($method, 'Until')) {
2637            try {
2638                $unit = static::singularUnit(substr($method, 0, -5));
2639
2640                return $this->range($parameters[0] ?? $this, $parameters[1] ?? 1, $unit);
2641            } catch (InvalidArgumentException $exception) {
2642                // Try macros
2643            }
2644        }
2645
2646        return static::bindMacroContext($this, function () use (&$method, &$parameters) {
2647            $macro = $this->getLocalMacro($method);
2648
2649            if (!$macro) {
2650                foreach ([$this->localGenericMacros ?: [], static::getGenericMacros()] as $list) {
2651                    foreach ($list as $callback) {
2652                        try {
2653                            return $this->executeCallable($callback, $method, ...$parameters);
2654                        } catch (BadMethodCallException $exception) {
2655                            continue;
2656                        }
2657                    }
2658                }
2659
2660                if ($this->localStrictModeEnabled ?? static::isStrictModeEnabled()) {
2661                    throw new UnknownMethodException($method);
2662                }
2663
2664                return null;
2665            }
2666
2667            return $this->executeCallable($macro, ...$parameters);
2668        });
2669    }
2670}
2671