<?php

declare(strict_types=1);

/**
 * This file is part of the Carbon package.
 *
 * (c) Brian Nesbitt <brian@nesbot.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Carbon\Traits;

use BadMethodCallException;
use Carbon\Carbon;
use Carbon\CarbonInterface;
use Carbon\CarbonPeriod;
use Carbon\CarbonTimeZone;
use Carbon\Exceptions\BadComparisonUnitException;
use Carbon\Exceptions\ImmutableException;
use Carbon\Exceptions\InvalidTimeZoneException;
use Carbon\Exceptions\UnitException;
use Carbon\Exceptions\UnknownGetterException;
use Carbon\Exceptions\UnknownMethodException;
use Carbon\Exceptions\UnknownSetterException;
use Carbon\Exceptions\UnknownUnitException;
use Carbon\FactoryImmutable;
use Carbon\Month;
use Carbon\Translator;
use Carbon\Unit;
use Carbon\WeekDay;
use Closure;
use DateInterval;
use DatePeriod;
use DateTime;
use DateTimeImmutable;
use DateTimeInterface;
use DateTimeZone;
use Generator;
use InvalidArgumentException;
use ReflectionException;
use Symfony\Component\Clock\NativeClock;
use Throwable;

/**
 * A simple API extension for DateTime.
 *
 * <autodoc generated by `composer phpdoc`>
 *
 * @property      string           $localeDayOfWeek                                                                   the day of week in current locale
 * @property      string           $shortLocaleDayOfWeek                                                              the abbreviated day of week in current locale
 * @property      string           $localeMonth                                                                       the month in current locale
 * @property      string           $shortLocaleMonth                                                                  the abbreviated month in current locale
 * @property      int              $year
 * @property      int              $yearIso
 * @property      int              $month
 * @property      int              $day
 * @property      int              $hour
 * @property      int              $minute
 * @property      int              $second
 * @property      int              $micro
 * @property      int              $microsecond
 * @property      int              $dayOfWeekIso                                                                      1 (for Monday) through 7 (for Sunday)
 * @property      int|float|string $timestamp                                                                         seconds since the Unix Epoch
 * @property      string           $englishDayOfWeek                                                                  the day of week in English
 * @property      string           $shortEnglishDayOfWeek                                                             the abbreviated day of week in English
 * @property      string           $englishMonth                                                                      the month in English
 * @property      string           $shortEnglishMonth                                                                 the abbreviated month in English
 * @property      int              $milliseconds
 * @property      int              $millisecond
 * @property      int              $milli
 * @property      int              $week                                                                              1 through 53
 * @property      int              $isoWeek                                                                           1 through 53
 * @property      int              $weekYear                                                                          year according to week format
 * @property      int              $isoWeekYear                                                                       year according to ISO week format
 * @property      int              $age                                                                               does a diffInYears() with default parameters
 * @property      int              $offset                                                                            the timezone offset in seconds from UTC
 * @property      int              $offsetMinutes                                                                     the timezone offset in minutes from UTC
 * @property      int              $offsetHours                                                                       the timezone offset in hours from UTC
 * @property      CarbonTimeZone   $timezone                                                                          the current timezone
 * @property      CarbonTimeZone   $tz                                                                                alias of $timezone
 * @property      int              $centuryOfMillennium                                                               The value of the century starting from the beginning of the current millennium
 * @property      int              $dayOfCentury                                                                      The value of the day starting from the beginning of the current century
 * @property      int              $dayOfDecade                                                                       The value of the day starting from the beginning of the current decade
 * @property      int              $dayOfMillennium                                                                   The value of the day starting from the beginning of the current millennium
 * @property      int              $dayOfMonth                                                                        The value of the day starting from the beginning of the current month
 * @property      int              $dayOfQuarter                                                                      The value of the day starting from the beginning of the current quarter
 * @property      int              $dayOfWeek                                                                         0 (for Sunday) through 6 (for Saturday)
 * @property      int              $dayOfYear                                                                         1 through 366
 * @property      int              $decadeOfCentury                                                                   The value of the decade starting from the beginning of the current century
 * @property      int              $decadeOfMillennium                                                                The value of the decade starting from the beginning of the current millennium
 * @property      int              $hourOfCentury                                                                     The value of the hour starting from the beginning of the current century
 * @property      int              $hourOfDay                                                                         The value of the hour starting from the beginning of the current day
 * @property      int              $hourOfDecade                                                                      The value of the hour starting from the beginning of the current decade
 * @property      int              $hourOfMillennium                                                                  The value of the hour starting from the beginning of the current millennium
 * @property      int              $hourOfMonth                                                                       The value of the hour starting from the beginning of the current month
 * @property      int              $hourOfQuarter                                                                     The value of the hour starting from the beginning of the current quarter
 * @property      int              $hourOfWeek                                                                        The value of the hour starting from the beginning of the current week
 * @property      int              $hourOfYear                                                                        The value of the hour starting from the beginning of the current year
 * @property      int              $microsecondOfCentury                                                              The value of the microsecond starting from the beginning of the current century
 * @property      int              $microsecondOfDay                                                                  The value of the microsecond starting from the beginning of the current day
 * @property      int              $microsecondOfDecade                                                               The value of the microsecond starting from the beginning of the current decade
 * @property      int              $microsecondOfHour                                                                 The value of the microsecond starting from the beginning of the current hour
 * @property      int              $microsecondOfMillennium                                                           The value of the microsecond starting from the beginning of the current millennium
 * @property      int              $microsecondOfMillisecond                                                          The value of the microsecond starting from the beginning of the current millisecond
 * @property      int              $microsecondOfMinute                                                               The value of the microsecond starting from the beginning of the current minute
 * @property      int              $microsecondOfMonth                                                                The value of the microsecond starting from the beginning of the current month
 * @property      int              $microsecondOfQuarter                                                              The value of the microsecond starting from the beginning of the current quarter
 * @property      int              $microsecondOfSecond                                                               The value of the microsecond starting from the beginning of the current second
 * @property      int              $microsecondOfWeek                                                                 The value of the microsecond starting from the beginning of the current week
 * @property      int              $microsecondOfYear                                                                 The value of the microsecond starting from the beginning of the current year
 * @property      int              $millisecondOfCentury                                                              The value of the millisecond starting from the beginning of the current century
 * @property      int              $millisecondOfDay                                                                  The value of the millisecond starting from the beginning of the current day
 * @property      int              $millisecondOfDecade                                                               The value of the millisecond starting from the beginning of the current decade
 * @property      int              $millisecondOfHour                                                                 The value of the millisecond starting from the beginning of the current hour
 * @property      int              $millisecondOfMillennium                                                           The value of the millisecond starting from the beginning of the current millennium
 * @property      int              $millisecondOfMinute                                                               The value of the millisecond starting from the beginning of the current minute
 * @property      int              $millisecondOfMonth                                                                The value of the millisecond starting from the beginning of the current month
 * @property      int              $millisecondOfQuarter                                                              The value of the millisecond starting from the beginning of the current quarter
 * @property      int              $millisecondOfSecond                                                               The value of the millisecond starting from the beginning of the current second
 * @property      int              $millisecondOfWeek                                                                 The value of the millisecond starting from the beginning of the current week
 * @property      int              $millisecondOfYear                                                                 The value of the millisecond starting from the beginning of the current year
 * @property      int              $minuteOfCentury                                                                   The value of the minute starting from the beginning of the current century
 * @property      int              $minuteOfDay                                                                       The value of the minute starting from the beginning of the current day
 * @property      int              $minuteOfDecade                                                                    The value of the minute starting from the beginning of the current decade
 * @property      int              $minuteOfHour                                                                      The value of the minute starting from the beginning of the current hour
 * @property      int              $minuteOfMillennium                                                                The value of the minute starting from the beginning of the current millennium
 * @property      int              $minuteOfMonth                                                                     The value of the minute starting from the beginning of the current month
 * @property      int              $minuteOfQuarter                                                                   The value of the minute starting from the beginning of the current quarter
 * @property      int              $minuteOfWeek                                                                      The value of the minute starting from the beginning of the current week
 * @property      int              $minuteOfYear                                                                      The value of the minute starting from the beginning of the current year
 * @property      int              $monthOfCentury                                                                    The value of the month starting from the beginning of the current century
 * @property      int              $monthOfDecade                                                                     The value of the month starting from the beginning of the current decade
 * @property      int              $monthOfMillennium                                                                 The value of the month starting from the beginning of the current millennium
 * @property      int              $monthOfQuarter                                                                    The value of the month starting from the beginning of the current quarter
 * @property      int              $monthOfYear                                                                       The value of the month starting from the beginning of the current year
 * @property      int              $quarterOfCentury                                                                  The value of the quarter starting from the beginning of the current century
 * @property      int              $quarterOfDecade                                                                   The value of the quarter starting from the beginning of the current decade
 * @property      int              $quarterOfMillennium                                                               The value of the quarter starting from the beginning of the current millennium
 * @property      int              $quarterOfYear                                                                     The value of the quarter starting from the beginning of the current year
 * @property      int              $secondOfCentury                                                                   The value of the second starting from the beginning of the current century
 * @property      int              $secondOfDay                                                                       The value of the second starting from the beginning of the current day
 * @property      int              $secondOfDecade                                                                    The value of the second starting from the beginning of the current decade
 * @property      int              $secondOfHour                                                                      The value of the second starting from the beginning of the current hour
 * @property      int              $secondOfMillennium                                                                The value of the second starting from the beginning of the current millennium
 * @property      int              $secondOfMinute                                                                    The value of the second starting from the beginning of the current minute
 * @property      int              $secondOfMonth                                                                     The value of the second starting from the beginning of the current month
 * @property      int              $secondOfQuarter                                                                   The value of the second starting from the beginning of the current quarter
 * @property      int              $secondOfWeek                                                                      The value of the second starting from the beginning of the current week
 * @property      int              $secondOfYear                                                                      The value of the second starting from the beginning of the current year
 * @property      int              $weekOfCentury                                                                     The value of the week starting from the beginning of the current century
 * @property      int              $weekOfDecade                                                                      The value of the week starting from the beginning of the current decade
 * @property      int              $weekOfMillennium                                                                  The value of the week starting from the beginning of the current millennium
 * @property      int              $weekOfMonth                                                                       1 through 5
 * @property      int              $weekOfQuarter                                                                     The value of the week starting from the beginning of the current quarter
 * @property      int              $weekOfYear                                                                        ISO-8601 week number of year, weeks starting on Monday
 * @property      int              $yearOfCentury                                                                     The value of the year starting from the beginning of the current century
 * @property      int              $yearOfDecade                                                                      The value of the year starting from the beginning of the current decade
 * @property      int              $yearOfMillennium                                                                  The value of the year starting from the beginning of the current millennium
 * @property-read string           $latinMeridiem                                                                     "am"/"pm" (Ante meridiem or Post meridiem latin lowercase mark)
 * @property-read string           $latinUpperMeridiem                                                                "AM"/"PM" (Ante meridiem or Post meridiem latin uppercase mark)
 * @property-read string           $timezoneAbbreviatedName                                                           the current timezone abbreviated name
 * @property-read string           $tzAbbrName                                                                        alias of $timezoneAbbreviatedName
 * @property-read string           $dayName                                                                           long name of weekday translated according to Carbon locale, in english if no translation available for current language
 * @property-read string           $shortDayName                                                                      short name of weekday translated according to Carbon locale, in english if no translation available for current language
 * @property-read string           $minDayName                                                                        very short name of weekday translated according to Carbon locale, in english if no translation available for current language
 * @property-read string           $monthName                                                                         long name of month translated according to Carbon locale, in english if no translation available for current language
 * @property-read string           $shortMonthName                                                                    short name of month translated according to Carbon locale, in english if no translation available for current language
 * @property-read string           $meridiem                                                                          lowercase meridiem mark translated according to Carbon locale, in latin if no translation available for current language
 * @property-read string           $upperMeridiem                                                                     uppercase meridiem mark translated according to Carbon locale, in latin if no translation available for current language
 * @property-read int              $noZeroHour                                                                        current hour from 1 to 24
 * @property-read int              $isoWeeksInYear                                                                    51 through 53
 * @property-read int              $weekNumberInMonth                                                                 1 through 5
 * @property-read int              $firstWeekDay                                                                      0 through 6
 * @property-read int              $lastWeekDay                                                                       0 through 6
 * @property-read int              $quarter                                                                           the quarter of this instance, 1 - 4
 * @property-read int              $decade                                                                            the decade of this instance
 * @property-read int              $century                                                                           the century of this instance
 * @property-read int              $millennium                                                                        the millennium of this instance
 * @property-read bool             $dst                                                                               daylight savings time indicator, true if DST, false otherwise
 * @property-read bool             $local                                                                             checks if the timezone is local, true if local, false otherwise
 * @property-read bool             $utc                                                                               checks if the timezone is UTC, true if UTC, false otherwise
 * @property-read string           $timezoneName                                                                      the current timezone name
 * @property-read string           $tzName                                                                            alias of $timezoneName
 * @property-read string           $locale                                                                            locale of the current instance
 * @property-read int              $centuriesInMillennium                                                             The number of centuries contained in the current millennium
 * @property-read int              $daysInCentury                                                                     The number of days contained in the current century
 * @property-read int              $daysInDecade                                                                      The number of days contained in the current decade
 * @property-read int              $daysInMillennium                                                                  The number of days contained in the current millennium
 * @property-read int              $daysInMonth                                                                       number of days in the given month
 * @property-read int              $daysInQuarter                                                                     The number of days contained in the current quarter
 * @property-read int              $daysInWeek                                                                        The number of days contained in the current week
 * @property-read int              $daysInYear                                                                        365 or 366
 * @property-read int              $decadesInCentury                                                                  The number of decades contained in the current century
 * @property-read int              $decadesInMillennium                                                               The number of decades contained in the current millennium
 * @property-read int              $hoursInCentury                                                                    The number of hours contained in the current century
 * @property-read int              $hoursInDay                                                                        The number of hours contained in the current day
 * @property-read int              $hoursInDecade                                                                     The number of hours contained in the current decade
 * @property-read int              $hoursInMillennium                                                                 The number of hours contained in the current millennium
 * @property-read int              $hoursInMonth                                                                      The number of hours contained in the current month
 * @property-read int              $hoursInQuarter                                                                    The number of hours contained in the current quarter
 * @property-read int              $hoursInWeek                                                                       The number of hours contained in the current week
 * @property-read int              $hoursInYear                                                                       The number of hours contained in the current year
 * @property-read int              $microsecondsInCentury                                                             The number of microseconds contained in the current century
 * @property-read int              $microsecondsInDay                                                                 The number of microseconds contained in the current day
 * @property-read int              $microsecondsInDecade                                                              The number of microseconds contained in the current decade
 * @property-read int              $microsecondsInHour                                                                The number of microseconds contained in the current hour
 * @property-read int              $microsecondsInMillennium                                                          The number of microseconds contained in the current millennium
 * @property-read int              $microsecondsInMillisecond                                                         The number of microseconds contained in the current millisecond
 * @property-read int              $microsecondsInMinute                                                              The number of microseconds contained in the current minute
 * @property-read int              $microsecondsInMonth                                                               The number of microseconds contained in the current month
 * @property-read int              $microsecondsInQuarter                                                             The number of microseconds contained in the current quarter
 * @property-read int              $microsecondsInSecond                                                              The number of microseconds contained in the current second
 * @property-read int              $microsecondsInWeek                                                                The number of microseconds contained in the current week
 * @property-read int              $microsecondsInYear                                                                The number of microseconds contained in the current year
 * @property-read int              $millisecondsInCentury                                                             The number of milliseconds contained in the current century
 * @property-read int              $millisecondsInDay                                                                 The number of milliseconds contained in the current day
 * @property-read int              $millisecondsInDecade                                                              The number of milliseconds contained in the current decade
 * @property-read int              $millisecondsInHour                                                                The number of milliseconds contained in the current hour
 * @property-read int              $millisecondsInMillennium                                                          The number of milliseconds contained in the current millennium
 * @property-read int              $millisecondsInMinute                                                              The number of milliseconds contained in the current minute
 * @property-read int              $millisecondsInMonth                                                               The number of milliseconds contained in the current month
 * @property-read int              $millisecondsInQuarter                                                             The number of milliseconds contained in the current quarter
 * @property-read int              $millisecondsInSecond                                                              The number of milliseconds contained in the current second
 * @property-read int              $millisecondsInWeek                                                                The number of milliseconds contained in the current week
 * @property-read int              $millisecondsInYear                                                                The number of milliseconds contained in the current year
 * @property-read int              $minutesInCentury                                                                  The number of minutes contained in the current century
 * @property-read int              $minutesInDay                                                                      The number of minutes contained in the current day
 * @property-read int              $minutesInDecade                                                                   The number of minutes contained in the current decade
 * @property-read int              $minutesInHour                                                                     The number of minutes contained in the current hour
 * @property-read int              $minutesInMillennium                                                               The number of minutes contained in the current millennium
 * @property-read int              $minutesInMonth                                                                    The number of minutes contained in the current month
 * @property-read int              $minutesInQuarter                                                                  The number of minutes contained in the current quarter
 * @property-read int              $minutesInWeek                                                                     The number of minutes contained in the current week
 * @property-read int              $minutesInYear                                                                     The number of minutes contained in the current year
 * @property-read int              $monthsInCentury                                                                   The number of months contained in the current century
 * @property-read int              $monthsInDecade                                                                    The number of months contained in the current decade
 * @property-read int              $monthsInMillennium                                                                The number of months contained in the current millennium
 * @property-read int              $monthsInQuarter                                                                   The number of months contained in the current quarter
 * @property-read int              $monthsInYear                                                                      The number of months contained in the current year
 * @property-read int              $quartersInCentury                                                                 The number of quarters contained in the current century
 * @property-read int              $quartersInDecade                                                                  The number of quarters contained in the current decade
 * @property-read int              $quartersInMillennium                                                              The number of quarters contained in the current millennium
 * @property-read int              $quartersInYear                                                                    The number of quarters contained in the current year
 * @property-read int              $secondsInCentury                                                                  The number of seconds contained in the current century
 * @property-read int              $secondsInDay                                                                      The number of seconds contained in the current day
 * @property-read int              $secondsInDecade                                                                   The number of seconds contained in the current decade
 * @property-read int              $secondsInHour                                                                     The number of seconds contained in the current hour
 * @property-read int              $secondsInMillennium                                                               The number of seconds contained in the current millennium
 * @property-read int              $secondsInMinute                                                                   The number of seconds contained in the current minute
 * @property-read int              $secondsInMonth                                                                    The number of seconds contained in the current month
 * @property-read int              $secondsInQuarter                                                                  The number of seconds contained in the current quarter
 * @property-read int              $secondsInWeek                                                                     The number of seconds contained in the current week
 * @property-read int              $secondsInYear                                                                     The number of seconds contained in the current year
 * @property-read int              $weeksInCentury                                                                    The number of weeks contained in the current century
 * @property-read int              $weeksInDecade                                                                     The number of weeks contained in the current decade
 * @property-read int              $weeksInMillennium                                                                 The number of weeks contained in the current millennium
 * @property-read int              $weeksInMonth                                                                      The number of weeks contained in the current month
 * @property-read int              $weeksInQuarter                                                                    The number of weeks contained in the current quarter
 * @property-read int              $weeksInYear                                                                       51 through 53
 * @property-read int              $yearsInCentury                                                                    The number of years contained in the current century
 * @property-read int              $yearsInDecade                                                                     The number of years contained in the current decade
 * @property-read int              $yearsInMillennium                                                                 The number of years contained in the current millennium
 *
 * @method        bool             isUtc()                                                                            Check if the current instance has UTC timezone. (Both isUtc and isUTC cases are valid.)
 * @method        bool             isLocal()                                                                          Check if the current instance has non-UTC timezone.
 * @method        bool             isValid()                                                                          Check if the current instance is a valid date.
 * @method        bool             isDST()                                                                            Check if the current instance is in a daylight saving time.
 * @method        bool             isSunday()                                                                         Checks if the instance day is sunday.
 * @method        bool             isMonday()                                                                         Checks if the instance day is monday.
 * @method        bool             isTuesday()                                                                        Checks if the instance day is tuesday.
 * @method        bool             isWednesday()                                                                      Checks if the instance day is wednesday.
 * @method        bool             isThursday()                                                                       Checks if the instance day is thursday.
 * @method        bool             isFriday()                                                                         Checks if the instance day is friday.
 * @method        bool             isSaturday()                                                                       Checks if the instance day is saturday.
 * @method        bool             isSameYear(DateTimeInterface|string $date)                                         Checks if the given date is in the same year as the instance. If null passed, compare to now (with the same timezone).
 * @method        bool             isCurrentYear()                                                                    Checks if the instance is in the same year as the current moment.
 * @method        bool             isNextYear()                                                                       Checks if the instance is in the same year as the current moment next year.
 * @method        bool             isLastYear()                                                                       Checks if the instance is in the same year as the current moment last year.
 * @method        bool             isCurrentMonth()                                                                   Checks if the instance is in the same month as the current moment.
 * @method        bool             isNextMonth()                                                                      Checks if the instance is in the same month as the current moment next month.
 * @method        bool             isLastMonth()                                                                      Checks if the instance is in the same month as the current moment last month.
 * @method        bool             isSameWeek(DateTimeInterface|string $date)                                         Checks if the given date is in the same week as the instance. If null passed, compare to now (with the same timezone).
 * @method        bool             isCurrentWeek()                                                                    Checks if the instance is in the same week as the current moment.
 * @method        bool             isNextWeek()                                                                       Checks if the instance is in the same week as the current moment next week.
 * @method        bool             isLastWeek()                                                                       Checks if the instance is in the same week as the current moment last week.
 * @method        bool             isSameDay(DateTimeInterface|string $date)                                          Checks if the given date is in the same day as the instance. If null passed, compare to now (with the same timezone).
 * @method        bool             isCurrentDay()                                                                     Checks if the instance is in the same day as the current moment.
 * @method        bool             isNextDay()                                                                        Checks if the instance is in the same day as the current moment next day.
 * @method        bool             isLastDay()                                                                        Checks if the instance is in the same day as the current moment last day.
 * @method        bool             isSameHour(DateTimeInterface|string $date)                                         Checks if the given date is in the same hour as the instance. If null passed, compare to now (with the same timezone).
 * @method        bool             isCurrentHour()                                                                    Checks if the instance is in the same hour as the current moment.
 * @method        bool             isNextHour()                                                                       Checks if the instance is in the same hour as the current moment next hour.
 * @method        bool             isLastHour()                                                                       Checks if the instance is in the same hour as the current moment last hour.
 * @method        bool             isSameMinute(DateTimeInterface|string $date)                                       Checks if the given date is in the same minute as the instance. If null passed, compare to now (with the same timezone).
 * @method        bool             isCurrentMinute()                                                                  Checks if the instance is in the same minute as the current moment.
 * @method        bool             isNextMinute()                                                                     Checks if the instance is in the same minute as the current moment next minute.
 * @method        bool             isLastMinute()                                                                     Checks if the instance is in the same minute as the current moment last minute.
 * @method        bool             isSameSecond(DateTimeInterface|string $date)                                       Checks if the given date is in the same second as the instance. If null passed, compare to now (with the same timezone).
 * @method        bool             isCurrentSecond()                                                                  Checks if the instance is in the same second as the current moment.
 * @method        bool             isNextSecond()                                                                     Checks if the instance is in the same second as the current moment next second.
 * @method        bool             isLastSecond()                                                                     Checks if the instance is in the same second as the current moment last second.
 * @method        bool             isSameMilli(DateTimeInterface|string $date)                                        Checks if the given date is in the same millisecond as the instance. If null passed, compare to now (with the same timezone).
 * @method        bool             isCurrentMilli()                                                                   Checks if the instance is in the same millisecond as the current moment.
 * @method        bool             isNextMilli()                                                                      Checks if the instance is in the same millisecond as the current moment next millisecond.
 * @method        bool             isLastMilli()                                                                      Checks if the instance is in the same millisecond as the current moment last millisecond.
 * @method        bool             isSameMillisecond(DateTimeInterface|string $date)                                  Checks if the given date is in the same millisecond as the instance. If null passed, compare to now (with the same timezone).
 * @method        bool             isCurrentMillisecond()                                                             Checks if the instance is in the same millisecond as the current moment.
 * @method        bool             isNextMillisecond()                                                                Checks if the instance is in the same millisecond as the current moment next millisecond.
 * @method        bool             isLastMillisecond()                                                                Checks if the instance is in the same millisecond as the current moment last millisecond.
 * @method        bool             isSameMicro(DateTimeInterface|string $date)                                        Checks if the given date is in the same microsecond as the instance. If null passed, compare to now (with the same timezone).
 * @method        bool             isCurrentMicro()                                                                   Checks if the instance is in the same microsecond as the current moment.
 * @method        bool             isNextMicro()                                                                      Checks if the instance is in the same microsecond as the current moment next microsecond.
 * @method        bool             isLastMicro()                                                                      Checks if the instance is in the same microsecond as the current moment last microsecond.
 * @method        bool             isSameMicrosecond(DateTimeInterface|string $date)                                  Checks if the given date is in the same microsecond as the instance. If null passed, compare to now (with the same timezone).
 * @method        bool             isCurrentMicrosecond()                                                             Checks if the instance is in the same microsecond as the current moment.
 * @method        bool             isNextMicrosecond()                                                                Checks if the instance is in the same microsecond as the current moment next microsecond.
 * @method        bool             isLastMicrosecond()                                                                Checks if the instance is in the same microsecond as the current moment last microsecond.
 * @method        bool             isSameDecade(DateTimeInterface|string $date)                                       Checks if the given date is in the same decade as the instance. If null passed, compare to now (with the same timezone).
 * @method        bool             isCurrentDecade()                                                                  Checks if the instance is in the same decade as the current moment.
 * @method        bool             isNextDecade()                                                                     Checks if the instance is in the same decade as the current moment next decade.
 * @method        bool             isLastDecade()                                                                     Checks if the instance is in the same decade as the current moment last decade.
 * @method        bool             isSameCentury(DateTimeInterface|string $date)                                      Checks if the given date is in the same century as the instance. If null passed, compare to now (with the same timezone).
 * @method        bool             isCurrentCentury()                                                                 Checks if the instance is in the same century as the current moment.
 * @method        bool             isNextCentury()                                                                    Checks if the instance is in the same century as the current moment next century.
 * @method        bool             isLastCentury()                                                                    Checks if the instance is in the same century as the current moment last century.
 * @method        bool             isSameMillennium(DateTimeInterface|string $date)                                   Checks if the given date is in the same millennium as the instance. If null passed, compare to now (with the same timezone).
 * @method        bool             isCurrentMillennium()                                                              Checks if the instance is in the same millennium as the current moment.
 * @method        bool             isNextMillennium()                                                                 Checks if the instance is in the same millennium as the current moment next millennium.
 * @method        bool             isLastMillennium()                                                                 Checks if the instance is in the same millennium as the current moment last millennium.
 * @method        bool             isCurrentQuarter()                                                                 Checks if the instance is in the same quarter as the current moment.
 * @method        bool             isNextQuarter()                                                                    Checks if the instance is in the same quarter as the current moment next quarter.
 * @method        bool             isLastQuarter()                                                                    Checks if the instance is in the same quarter as the current moment last quarter.
 * @method        CarbonInterface  years(int $value)                                                                  Set current instance year to the given value.
 * @method        CarbonInterface  year(int $value)                                                                   Set current instance year to the given value.
 * @method        CarbonInterface  setYears(int $value)                                                               Set current instance year to the given value.
 * @method        CarbonInterface  setYear(int $value)                                                                Set current instance year to the given value.
 * @method        CarbonInterface  months(Month|int $value)                                                           Set current instance month to the given value.
 * @method        CarbonInterface  month(Month|int $value)                                                            Set current instance month to the given value.
 * @method        CarbonInterface  setMonths(Month|int $value)                                                        Set current instance month to the given value.
 * @method        CarbonInterface  setMonth(Month|int $value)                                                         Set current instance month to the given value.
 * @method        CarbonInterface  days(int $value)                                                                   Set current instance day to the given value.
 * @method        CarbonInterface  day(int $value)                                                                    Set current instance day to the given value.
 * @method        CarbonInterface  setDays(int $value)                                                                Set current instance day to the given value.
 * @method        CarbonInterface  setDay(int $value)                                                                 Set current instance day to the given value.
 * @method        CarbonInterface  hours(int $value)                                                                  Set current instance hour to the given value.
 * @method        CarbonInterface  hour(int $value)                                                                   Set current instance hour to the given value.
 * @method        CarbonInterface  setHours(int $value)                                                               Set current instance hour to the given value.
 * @method        CarbonInterface  setHour(int $value)                                                                Set current instance hour to the given value.
 * @method        CarbonInterface  minutes(int $value)                                                                Set current instance minute to the given value.
 * @method        CarbonInterface  minute(int $value)                                                                 Set current instance minute to the given value.
 * @method        CarbonInterface  setMinutes(int $value)                                                             Set current instance minute to the given value.
 * @method        CarbonInterface  setMinute(int $value)                                                              Set current instance minute to the given value.
 * @method        CarbonInterface  seconds(int $value)                                                                Set current instance second to the given value.
 * @method        CarbonInterface  second(int $value)                                                                 Set current instance second to the given value.
 * @method        CarbonInterface  setSeconds(int $value)                                                             Set current instance second to the given value.
 * @method        CarbonInterface  setSecond(int $value)                                                              Set current instance second to the given value.
 * @method        CarbonInterface  millis(int $value)                                                                 Set current instance millisecond to the given value.
 * @method        CarbonInterface  milli(int $value)                                                                  Set current instance millisecond to the given value.
 * @method        CarbonInterface  setMillis(int $value)                                                              Set current instance millisecond to the given value.
 * @method        CarbonInterface  setMilli(int $value)                                                               Set current instance millisecond to the given value.
 * @method        CarbonInterface  milliseconds(int $value)                                                           Set current instance millisecond to the given value.
 * @method        CarbonInterface  millisecond(int $value)                                                            Set current instance millisecond to the given value.
 * @method        CarbonInterface  setMilliseconds(int $value)                                                        Set current instance millisecond to the given value.
 * @method        CarbonInterface  setMillisecond(int $value)                                                         Set current instance millisecond to the given value.
 * @method        CarbonInterface  micros(int $value)                                                                 Set current instance microsecond to the given value.
 * @method        CarbonInterface  micro(int $value)                                                                  Set current instance microsecond to the given value.
 * @method        CarbonInterface  setMicros(int $value)                                                              Set current instance microsecond to the given value.
 * @method        CarbonInterface  setMicro(int $value)                                                               Set current instance microsecond to the given value.
 * @method        CarbonInterface  microseconds(int $value)                                                           Set current instance microsecond to the given value.
 * @method        CarbonInterface  microsecond(int $value)                                                            Set current instance microsecond to the given value.
 * @method        CarbonInterface  setMicroseconds(int $value)                                                        Set current instance microsecond to the given value.
 * @method        CarbonInterface  setMicrosecond(int $value)                                                         Set current instance microsecond to the given value.
 * @method        CarbonInterface  addYears(int|float $value = 1)                                                     Add years (the $value count passed in) to the instance (using date interval).
 * @method        CarbonInterface  addYear()                                                                          Add one year to the instance (using date interval).
 * @method        CarbonInterface  subYears(int|float $value = 1)                                                     Sub years (the $value count passed in) to the instance (using date interval).
 * @method        CarbonInterface  subYear()                                                                          Sub one year to the instance (using date interval).
 * @method        CarbonInterface  addYearsWithOverflow(int|float $value = 1)                                         Add years (the $value count passed in) to the instance (using date interval) with overflow explicitly allowed.
 * @method        CarbonInterface  addYearWithOverflow()                                                              Add one year to the instance (using date interval) with overflow explicitly allowed.
 * @method        CarbonInterface  subYearsWithOverflow(int|float $value = 1)                                         Sub years (the $value count passed in) to the instance (using date interval) with overflow explicitly allowed.
 * @method        CarbonInterface  subYearWithOverflow()                                                              Sub one year to the instance (using date interval) with overflow explicitly allowed.
 * @method        CarbonInterface  addYearsWithoutOverflow(int|float $value = 1)                                      Add years (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  addYearWithoutOverflow()                                                           Add one year to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  subYearsWithoutOverflow(int|float $value = 1)                                      Sub years (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  subYearWithoutOverflow()                                                           Sub one year to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  addYearsWithNoOverflow(int|float $value = 1)                                       Add years (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  addYearWithNoOverflow()                                                            Add one year to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  subYearsWithNoOverflow(int|float $value = 1)                                       Sub years (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  subYearWithNoOverflow()                                                            Sub one year to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  addYearsNoOverflow(int|float $value = 1)                                           Add years (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  addYearNoOverflow()                                                                Add one year to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  subYearsNoOverflow(int|float $value = 1)                                           Sub years (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  subYearNoOverflow()                                                                Sub one year to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  addMonths(int|float $value = 1)                                                    Add months (the $value count passed in) to the instance (using date interval).
 * @method        CarbonInterface  addMonth()                                                                         Add one month to the instance (using date interval).
 * @method        CarbonInterface  subMonths(int|float $value = 1)                                                    Sub months (the $value count passed in) to the instance (using date interval).
 * @method        CarbonInterface  subMonth()                                                                         Sub one month to the instance (using date interval).
 * @method        CarbonInterface  addMonthsWithOverflow(int|float $value = 1)                                        Add months (the $value count passed in) to the instance (using date interval) with overflow explicitly allowed.
 * @method        CarbonInterface  addMonthWithOverflow()                                                             Add one month to the instance (using date interval) with overflow explicitly allowed.
 * @method        CarbonInterface  subMonthsWithOverflow(int|float $value = 1)                                        Sub months (the $value count passed in) to the instance (using date interval) with overflow explicitly allowed.
 * @method        CarbonInterface  subMonthWithOverflow()                                                             Sub one month to the instance (using date interval) with overflow explicitly allowed.
 * @method        CarbonInterface  addMonthsWithoutOverflow(int|float $value = 1)                                     Add months (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  addMonthWithoutOverflow()                                                          Add one month to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  subMonthsWithoutOverflow(int|float $value = 1)                                     Sub months (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  subMonthWithoutOverflow()                                                          Sub one month to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  addMonthsWithNoOverflow(int|float $value = 1)                                      Add months (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  addMonthWithNoOverflow()                                                           Add one month to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  subMonthsWithNoOverflow(int|float $value = 1)                                      Sub months (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  subMonthWithNoOverflow()                                                           Sub one month to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  addMonthsNoOverflow(int|float $value = 1)                                          Add months (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  addMonthNoOverflow()                                                               Add one month to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  subMonthsNoOverflow(int|float $value = 1)                                          Sub months (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  subMonthNoOverflow()                                                               Sub one month to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  addDays(int|float $value = 1)                                                      Add days (the $value count passed in) to the instance (using date interval).
 * @method        CarbonInterface  addDay()                                                                           Add one day to the instance (using date interval).
 * @method        CarbonInterface  subDays(int|float $value = 1)                                                      Sub days (the $value count passed in) to the instance (using date interval).
 * @method        CarbonInterface  subDay()                                                                           Sub one day to the instance (using date interval).
 * @method        CarbonInterface  addHours(int|float $value = 1)                                                     Add hours (the $value count passed in) to the instance (using date interval).
 * @method        CarbonInterface  addHour()                                                                          Add one hour to the instance (using date interval).
 * @method        CarbonInterface  subHours(int|float $value = 1)                                                     Sub hours (the $value count passed in) to the instance (using date interval).
 * @method        CarbonInterface  subHour()                                                                          Sub one hour to the instance (using date interval).
 * @method        CarbonInterface  addMinutes(int|float $value = 1)                                                   Add minutes (the $value count passed in) to the instance (using date interval).
 * @method        CarbonInterface  addMinute()                                                                        Add one minute to the instance (using date interval).
 * @method        CarbonInterface  subMinutes(int|float $value = 1)                                                   Sub minutes (the $value count passed in) to the instance (using date interval).
 * @method        CarbonInterface  subMinute()                                                                        Sub one minute to the instance (using date interval).
 * @method        CarbonInterface  addSeconds(int|float $value = 1)                                                   Add seconds (the $value count passed in) to the instance (using date interval).
 * @method        CarbonInterface  addSecond()                                                                        Add one second to the instance (using date interval).
 * @method        CarbonInterface  subSeconds(int|float $value = 1)                                                   Sub seconds (the $value count passed in) to the instance (using date interval).
 * @method        CarbonInterface  subSecond()                                                                        Sub one second to the instance (using date interval).
 * @method        CarbonInterface  addMillis(int|float $value = 1)                                                    Add milliseconds (the $value count passed in) to the instance (using date interval).
 * @method        CarbonInterface  addMilli()                                                                         Add one millisecond to the instance (using date interval).
 * @method        CarbonInterface  subMillis(int|float $value = 1)                                                    Sub milliseconds (the $value count passed in) to the instance (using date interval).
 * @method        CarbonInterface  subMilli()                                                                         Sub one millisecond to the instance (using date interval).
 * @method        CarbonInterface  addMilliseconds(int|float $value = 1)                                              Add milliseconds (the $value count passed in) to the instance (using date interval).
 * @method        CarbonInterface  addMillisecond()                                                                   Add one millisecond to the instance (using date interval).
 * @method        CarbonInterface  subMilliseconds(int|float $value = 1)                                              Sub milliseconds (the $value count passed in) to the instance (using date interval).
 * @method        CarbonInterface  subMillisecond()                                                                   Sub one millisecond to the instance (using date interval).
 * @method        CarbonInterface  addMicros(int|float $value = 1)                                                    Add microseconds (the $value count passed in) to the instance (using date interval).
 * @method        CarbonInterface  addMicro()                                                                         Add one microsecond to the instance (using date interval).
 * @method        CarbonInterface  subMicros(int|float $value = 1)                                                    Sub microseconds (the $value count passed in) to the instance (using date interval).
 * @method        CarbonInterface  subMicro()                                                                         Sub one microsecond to the instance (using date interval).
 * @method        CarbonInterface  addMicroseconds(int|float $value = 1)                                              Add microseconds (the $value count passed in) to the instance (using date interval).
 * @method        CarbonInterface  addMicrosecond()                                                                   Add one microsecond to the instance (using date interval).
 * @method        CarbonInterface  subMicroseconds(int|float $value = 1)                                              Sub microseconds (the $value count passed in) to the instance (using date interval).
 * @method        CarbonInterface  subMicrosecond()                                                                   Sub one microsecond to the instance (using date interval).
 * @method        CarbonInterface  addMillennia(int|float $value = 1)                                                 Add millennia (the $value count passed in) to the instance (using date interval).
 * @method        CarbonInterface  addMillennium()                                                                    Add one millennium to the instance (using date interval).
 * @method        CarbonInterface  subMillennia(int|float $value = 1)                                                 Sub millennia (the $value count passed in) to the instance (using date interval).
 * @method        CarbonInterface  subMillennium()                                                                    Sub one millennium to the instance (using date interval).
 * @method        CarbonInterface  addMillenniaWithOverflow(int|float $value = 1)                                     Add millennia (the $value count passed in) to the instance (using date interval) with overflow explicitly allowed.
 * @method        CarbonInterface  addMillenniumWithOverflow()                                                        Add one millennium to the instance (using date interval) with overflow explicitly allowed.
 * @method        CarbonInterface  subMillenniaWithOverflow(int|float $value = 1)                                     Sub millennia (the $value count passed in) to the instance (using date interval) with overflow explicitly allowed.
 * @method        CarbonInterface  subMillenniumWithOverflow()                                                        Sub one millennium to the instance (using date interval) with overflow explicitly allowed.
 * @method        CarbonInterface  addMillenniaWithoutOverflow(int|float $value = 1)                                  Add millennia (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  addMillenniumWithoutOverflow()                                                     Add one millennium to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  subMillenniaWithoutOverflow(int|float $value = 1)                                  Sub millennia (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  subMillenniumWithoutOverflow()                                                     Sub one millennium to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  addMillenniaWithNoOverflow(int|float $value = 1)                                   Add millennia (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  addMillenniumWithNoOverflow()                                                      Add one millennium to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  subMillenniaWithNoOverflow(int|float $value = 1)                                   Sub millennia (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  subMillenniumWithNoOverflow()                                                      Sub one millennium to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  addMillenniaNoOverflow(int|float $value = 1)                                       Add millennia (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  addMillenniumNoOverflow()                                                          Add one millennium to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  subMillenniaNoOverflow(int|float $value = 1)                                       Sub millennia (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  subMillenniumNoOverflow()                                                          Sub one millennium to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  addCenturies(int|float $value = 1)                                                 Add centuries (the $value count passed in) to the instance (using date interval).
 * @method        CarbonInterface  addCentury()                                                                       Add one century to the instance (using date interval).
 * @method        CarbonInterface  subCenturies(int|float $value = 1)                                                 Sub centuries (the $value count passed in) to the instance (using date interval).
 * @method        CarbonInterface  subCentury()                                                                       Sub one century to the instance (using date interval).
 * @method        CarbonInterface  addCenturiesWithOverflow(int|float $value = 1)                                     Add centuries (the $value count passed in) to the instance (using date interval) with overflow explicitly allowed.
 * @method        CarbonInterface  addCenturyWithOverflow()                                                           Add one century to the instance (using date interval) with overflow explicitly allowed.
 * @method        CarbonInterface  subCenturiesWithOverflow(int|float $value = 1)                                     Sub centuries (the $value count passed in) to the instance (using date interval) with overflow explicitly allowed.
 * @method        CarbonInterface  subCenturyWithOverflow()                                                           Sub one century to the instance (using date interval) with overflow explicitly allowed.
 * @method        CarbonInterface  addCenturiesWithoutOverflow(int|float $value = 1)                                  Add centuries (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  addCenturyWithoutOverflow()                                                        Add one century to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  subCenturiesWithoutOverflow(int|float $value = 1)                                  Sub centuries (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  subCenturyWithoutOverflow()                                                        Sub one century to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  addCenturiesWithNoOverflow(int|float $value = 1)                                   Add centuries (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  addCenturyWithNoOverflow()                                                         Add one century to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  subCenturiesWithNoOverflow(int|float $value = 1)                                   Sub centuries (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  subCenturyWithNoOverflow()                                                         Sub one century to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  addCenturiesNoOverflow(int|float $value = 1)                                       Add centuries (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  addCenturyNoOverflow()                                                             Add one century to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  subCenturiesNoOverflow(int|float $value = 1)                                       Sub centuries (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  subCenturyNoOverflow()                                                             Sub one century to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  addDecades(int|float $value = 1)                                                   Add decades (the $value count passed in) to the instance (using date interval).
 * @method        CarbonInterface  addDecade()                                                                        Add one decade to the instance (using date interval).
 * @method        CarbonInterface  subDecades(int|float $value = 1)                                                   Sub decades (the $value count passed in) to the instance (using date interval).
 * @method        CarbonInterface  subDecade()                                                                        Sub one decade to the instance (using date interval).
 * @method        CarbonInterface  addDecadesWithOverflow(int|float $value = 1)                                       Add decades (the $value count passed in) to the instance (using date interval) with overflow explicitly allowed.
 * @method        CarbonInterface  addDecadeWithOverflow()                                                            Add one decade to the instance (using date interval) with overflow explicitly allowed.
 * @method        CarbonInterface  subDecadesWithOverflow(int|float $value = 1)                                       Sub decades (the $value count passed in) to the instance (using date interval) with overflow explicitly allowed.
 * @method        CarbonInterface  subDecadeWithOverflow()                                                            Sub one decade to the instance (using date interval) with overflow explicitly allowed.
 * @method        CarbonInterface  addDecadesWithoutOverflow(int|float $value = 1)                                    Add decades (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  addDecadeWithoutOverflow()                                                         Add one decade to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  subDecadesWithoutOverflow(int|float $value = 1)                                    Sub decades (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  subDecadeWithoutOverflow()                                                         Sub one decade to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  addDecadesWithNoOverflow(int|float $value = 1)                                     Add decades (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  addDecadeWithNoOverflow()                                                          Add one decade to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  subDecadesWithNoOverflow(int|float $value = 1)                                     Sub decades (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  subDecadeWithNoOverflow()                                                          Sub one decade to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  addDecadesNoOverflow(int|float $value = 1)                                         Add decades (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  addDecadeNoOverflow()                                                              Add one decade to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  subDecadesNoOverflow(int|float $value = 1)                                         Sub decades (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  subDecadeNoOverflow()                                                              Sub one decade to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  addQuarters(int|float $value = 1)                                                  Add quarters (the $value count passed in) to the instance (using date interval).
 * @method        CarbonInterface  addQuarter()                                                                       Add one quarter to the instance (using date interval).
 * @method        CarbonInterface  subQuarters(int|float $value = 1)                                                  Sub quarters (the $value count passed in) to the instance (using date interval).
 * @method        CarbonInterface  subQuarter()                                                                       Sub one quarter to the instance (using date interval).
 * @method        CarbonInterface  addQuartersWithOverflow(int|float $value = 1)                                      Add quarters (the $value count passed in) to the instance (using date interval) with overflow explicitly allowed.
 * @method        CarbonInterface  addQuarterWithOverflow()                                                           Add one quarter to the instance (using date interval) with overflow explicitly allowed.
 * @method        CarbonInterface  subQuartersWithOverflow(int|float $value = 1)                                      Sub quarters (the $value count passed in) to the instance (using date interval) with overflow explicitly allowed.
 * @method        CarbonInterface  subQuarterWithOverflow()                                                           Sub one quarter to the instance (using date interval) with overflow explicitly allowed.
 * @method        CarbonInterface  addQuartersWithoutOverflow(int|float $value = 1)                                   Add quarters (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  addQuarterWithoutOverflow()                                                        Add one quarter to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  subQuartersWithoutOverflow(int|float $value = 1)                                   Sub quarters (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  subQuarterWithoutOverflow()                                                        Sub one quarter to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  addQuartersWithNoOverflow(int|float $value = 1)                                    Add quarters (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  addQuarterWithNoOverflow()                                                         Add one quarter to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  subQuartersWithNoOverflow(int|float $value = 1)                                    Sub quarters (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  subQuarterWithNoOverflow()                                                         Sub one quarter to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  addQuartersNoOverflow(int|float $value = 1)                                        Add quarters (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  addQuarterNoOverflow()                                                             Add one quarter to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  subQuartersNoOverflow(int|float $value = 1)                                        Sub quarters (the $value count passed in) to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  subQuarterNoOverflow()                                                             Sub one quarter to the instance (using date interval) with overflow explicitly forbidden.
 * @method        CarbonInterface  addWeeks(int|float $value = 1)                                                     Add weeks (the $value count passed in) to the instance (using date interval).
 * @method        CarbonInterface  addWeek()                                                                          Add one week to the instance (using date interval).
 * @method        CarbonInterface  subWeeks(int|float $value = 1)                                                     Sub weeks (the $value count passed in) to the instance (using date interval).
 * @method        CarbonInterface  subWeek()                                                                          Sub one week to the instance (using date interval).
 * @method        CarbonInterface  addWeekdays(int|float $value = 1)                                                  Add weekdays (the $value count passed in) to the instance (using date interval).
 * @method        CarbonInterface  addWeekday()                                                                       Add one weekday to the instance (using date interval).
 * @method        CarbonInterface  subWeekdays(int|float $value = 1)                                                  Sub weekdays (the $value count passed in) to the instance (using date interval).
 * @method        CarbonInterface  subWeekday()                                                                       Sub one weekday to the instance (using date interval).
 * @method        CarbonInterface  addUTCMicros(int|float $value = 1)                                                 Add microseconds (the $value count passed in) to the instance (using timestamp).
 * @method        CarbonInterface  addUTCMicro()                                                                      Add one microsecond to the instance (using timestamp).
 * @method        CarbonInterface  subUTCMicros(int|float $value = 1)                                                 Sub microseconds (the $value count passed in) to the instance (using timestamp).
 * @method        CarbonInterface  subUTCMicro()                                                                      Sub one microsecond to the instance (using timestamp).
 * @method        CarbonPeriod     microsUntil($endDate = null, int|float $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.
 * @method        float            diffInUTCMicros(DateTimeInterface|string|null $date, bool $absolute = false)       Convert current and given date in UTC timezone and return a floating number of microseconds.
 * @method        CarbonInterface  addUTCMicroseconds(int|float $value = 1)                                           Add microseconds (the $value count passed in) to the instance (using timestamp).
 * @method        CarbonInterface  addUTCMicrosecond()                                                                Add one microsecond to the instance (using timestamp).
 * @method        CarbonInterface  subUTCMicroseconds(int|float $value = 1)                                           Sub microseconds (the $value count passed in) to the instance (using timestamp).
 * @method        CarbonInterface  subUTCMicrosecond()                                                                Sub one microsecond to the instance (using timestamp).
 * @method        CarbonPeriod     microsecondsUntil($endDate = null, int|float $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.
 * @method        float            diffInUTCMicroseconds(DateTimeInterface|string|null $date, bool $absolute = false) Convert current and given date in UTC timezone and return a floating number of microseconds.
 * @method        CarbonInterface  addUTCMillis(int|float $value = 1)                                                 Add milliseconds (the $value count passed in) to the instance (using timestamp).
 * @method        CarbonInterface  addUTCMilli()                                                                      Add one millisecond to the instance (using timestamp).
 * @method        CarbonInterface  subUTCMillis(int|float $value = 1)                                                 Sub milliseconds (the $value count passed in) to the instance (using timestamp).
 * @method        CarbonInterface  subUTCMilli()                                                                      Sub one millisecond to the instance (using timestamp).
 * @method        CarbonPeriod     millisUntil($endDate = null, int|float $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.
 * @method        float            diffInUTCMillis(DateTimeInterface|string|null $date, bool $absolute = false)       Convert current and given date in UTC timezone and return a floating number of milliseconds.
 * @method        CarbonInterface  addUTCMilliseconds(int|float $value = 1)                                           Add milliseconds (the $value count passed in) to the instance (using timestamp).
 * @method        CarbonInterface  addUTCMillisecond()                                                                Add one millisecond to the instance (using timestamp).
 * @method        CarbonInterface  subUTCMilliseconds(int|float $value = 1)                                           Sub milliseconds (the $value count passed in) to the instance (using timestamp).
 * @method        CarbonInterface  subUTCMillisecond()                                                                Sub one millisecond to the instance (using timestamp).
 * @method        CarbonPeriod     millisecondsUntil($endDate = null, int|float $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.
 * @method        float            diffInUTCMilliseconds(DateTimeInterface|string|null $date, bool $absolute = false) Convert current and given date in UTC timezone and return a floating number of milliseconds.
 * @method        CarbonInterface  addUTCSeconds(int|float $value = 1)                                                Add seconds (the $value count passed in) to the instance (using timestamp).
 * @method        CarbonInterface  addUTCSecond()                                                                     Add one second to the instance (using timestamp).
 * @method        CarbonInterface  subUTCSeconds(int|float $value = 1)                                                Sub seconds (the $value count passed in) to the instance (using timestamp).
 * @method        CarbonInterface  subUTCSecond()                                                                     Sub one second to the instance (using timestamp).
 * @method        CarbonPeriod     secondsUntil($endDate = null, int|float $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.
 * @method        float            diffInUTCSeconds(DateTimeInterface|string|null $date, bool $absolute = false)      Convert current and given date in UTC timezone and return a floating number of seconds.
 * @method        CarbonInterface  addUTCMinutes(int|float $value = 1)                                                Add minutes (the $value count passed in) to the instance (using timestamp).
 * @method        CarbonInterface  addUTCMinute()                                                                     Add one minute to the instance (using timestamp).
 * @method        CarbonInterface  subUTCMinutes(int|float $value = 1)                                                Sub minutes (the $value count passed in) to the instance (using timestamp).
 * @method        CarbonInterface  subUTCMinute()                                                                     Sub one minute to the instance (using timestamp).
 * @method        CarbonPeriod     minutesUntil($endDate = null, int|float $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.
 * @method        float            diffInUTCMinutes(DateTimeInterface|string|null $date, bool $absolute = false)      Convert current and given date in UTC timezone and return a floating number of minutes.
 * @method        CarbonInterface  addUTCHours(int|float $value = 1)                                                  Add hours (the $value count passed in) to the instance (using timestamp).
 * @method        CarbonInterface  addUTCHour()                                                                       Add one hour to the instance (using timestamp).
 * @method        CarbonInterface  subUTCHours(int|float $value = 1)                                                  Sub hours (the $value count passed in) to the instance (using timestamp).
 * @method        CarbonInterface  subUTCHour()                                                                       Sub one hour to the instance (using timestamp).
 * @method        CarbonPeriod     hoursUntil($endDate = null, int|float $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.
 * @method        float            diffInUTCHours(DateTimeInterface|string|null $date, bool $absolute = false)        Convert current and given date in UTC timezone and return a floating number of hours.
 * @method        CarbonInterface  addUTCDays(int|float $value = 1)                                                   Add days (the $value count passed in) to the instance (using timestamp).
 * @method        CarbonInterface  addUTCDay()                                                                        Add one day to the instance (using timestamp).
 * @method        CarbonInterface  subUTCDays(int|float $value = 1)                                                   Sub days (the $value count passed in) to the instance (using timestamp).
 * @method        CarbonInterface  subUTCDay()                                                                        Sub one day to the instance (using timestamp).
 * @method        CarbonPeriod     daysUntil($endDate = null, int|float $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.
 * @method        float            diffInUTCDays(DateTimeInterface|string|null $date, bool $absolute = false)         Convert current and given date in UTC timezone and return a floating number of days.
 * @method        CarbonInterface  addUTCWeeks(int|float $value = 1)                                                  Add weeks (the $value count passed in) to the instance (using timestamp).
 * @method        CarbonInterface  addUTCWeek()                                                                       Add one week to the instance (using timestamp).
 * @method        CarbonInterface  subUTCWeeks(int|float $value = 1)                                                  Sub weeks (the $value count passed in) to the instance (using timestamp).
 * @method        CarbonInterface  subUTCWeek()                                                                       Sub one week to the instance (using timestamp).
 * @method        CarbonPeriod     weeksUntil($endDate = null, int|float $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.
 * @method        float            diffInUTCWeeks(DateTimeInterface|string|null $date, bool $absolute = false)        Convert current and given date in UTC timezone and return a floating number of weeks.
 * @method        CarbonInterface  addUTCMonths(int|float $value = 1)                                                 Add months (the $value count passed in) to the instance (using timestamp).
 * @method        CarbonInterface  addUTCMonth()                                                                      Add one month to the instance (using timestamp).
 * @method        CarbonInterface  subUTCMonths(int|float $value = 1)                                                 Sub months (the $value count passed in) to the instance (using timestamp).
 * @method        CarbonInterface  subUTCMonth()                                                                      Sub one month to the instance (using timestamp).
 * @method        CarbonPeriod     monthsUntil($endDate = null, int|float $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.
 * @method        float            diffInUTCMonths(DateTimeInterface|string|null $date, bool $absolute = false)       Convert current and given date in UTC timezone and return a floating number of months.
 * @method        CarbonInterface  addUTCQuarters(int|float $value = 1)                                               Add quarters (the $value count passed in) to the instance (using timestamp).
 * @method        CarbonInterface  addUTCQuarter()                                                                    Add one quarter to the instance (using timestamp).
 * @method        CarbonInterface  subUTCQuarters(int|float $value = 1)                                               Sub quarters (the $value count passed in) to the instance (using timestamp).
 * @method        CarbonInterface  subUTCQuarter()                                                                    Sub one quarter to the instance (using timestamp).
 * @method        CarbonPeriod     quartersUntil($endDate = null, int|float $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.
 * @method        float            diffInUTCQuarters(DateTimeInterface|string|null $date, bool $absolute = false)     Convert current and given date in UTC timezone and return a floating number of quarters.
 * @method        CarbonInterface  addUTCYears(int|float $value = 1)                                                  Add years (the $value count passed in) to the instance (using timestamp).
 * @method        CarbonInterface  addUTCYear()                                                                       Add one year to the instance (using timestamp).
 * @method        CarbonInterface  subUTCYears(int|float $value = 1)                                                  Sub years (the $value count passed in) to the instance (using timestamp).
 * @method        CarbonInterface  subUTCYear()                                                                       Sub one year to the instance (using timestamp).
 * @method        CarbonPeriod     yearsUntil($endDate = null, int|float $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.
 * @method        float            diffInUTCYears(DateTimeInterface|string|null $date, bool $absolute = false)        Convert current and given date in UTC timezone and return a floating number of years.
 * @method        CarbonInterface  addUTCDecades(int|float $value = 1)                                                Add decades (the $value count passed in) to the instance (using timestamp).
 * @method        CarbonInterface  addUTCDecade()                                                                     Add one decade to the instance (using timestamp).
 * @method        CarbonInterface  subUTCDecades(int|float $value = 1)                                                Sub decades (the $value count passed in) to the instance (using timestamp).
 * @method        CarbonInterface  subUTCDecade()                                                                     Sub one decade to the instance (using timestamp).
 * @method        CarbonPeriod     decadesUntil($endDate = null, int|float $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.
 * @method        float            diffInUTCDecades(DateTimeInterface|string|null $date, bool $absolute = false)      Convert current and given date in UTC timezone and return a floating number of decades.
 * @method        CarbonInterface  addUTCCenturies(int|float $value = 1)                                              Add centuries (the $value count passed in) to the instance (using timestamp).
 * @method        CarbonInterface  addUTCCentury()                                                                    Add one century to the instance (using timestamp).
 * @method        CarbonInterface  subUTCCenturies(int|float $value = 1)                                              Sub centuries (the $value count passed in) to the instance (using timestamp).
 * @method        CarbonInterface  subUTCCentury()                                                                    Sub one century to the instance (using timestamp).
 * @method        CarbonPeriod     centuriesUntil($endDate = null, int|float $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.
 * @method        float            diffInUTCCenturies(DateTimeInterface|string|null $date, bool $absolute = false)    Convert current and given date in UTC timezone and return a floating number of centuries.
 * @method        CarbonInterface  addUTCMillennia(int|float $value = 1)                                              Add millennia (the $value count passed in) to the instance (using timestamp).
 * @method        CarbonInterface  addUTCMillennium()                                                                 Add one millennium to the instance (using timestamp).
 * @method        CarbonInterface  subUTCMillennia(int|float $value = 1)                                              Sub millennia (the $value count passed in) to the instance (using timestamp).
 * @method        CarbonInterface  subUTCMillennium()                                                                 Sub one millennium to the instance (using timestamp).
 * @method        CarbonPeriod     millenniaUntil($endDate = null, int|float $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.
 * @method        float            diffInUTCMillennia(DateTimeInterface|string|null $date, bool $absolute = false)    Convert current and given date in UTC timezone and return a floating number of millennia.
 * @method        CarbonInterface  roundYear(float $precision = 1, string $function = "round")                        Round the current instance year with given precision using the given function.
 * @method        CarbonInterface  roundYears(float $precision = 1, string $function = "round")                       Round the current instance year with given precision using the given function.
 * @method        CarbonInterface  floorYear(float $precision = 1)                                                    Truncate the current instance year with given precision.
 * @method        CarbonInterface  floorYears(float $precision = 1)                                                   Truncate the current instance year with given precision.
 * @method        CarbonInterface  ceilYear(float $precision = 1)                                                     Ceil the current instance year with given precision.
 * @method        CarbonInterface  ceilYears(float $precision = 1)                                                    Ceil the current instance year with given precision.
 * @method        CarbonInterface  roundMonth(float $precision = 1, string $function = "round")                       Round the current instance month with given precision using the given function.
 * @method        CarbonInterface  roundMonths(float $precision = 1, string $function = "round")                      Round the current instance month with given precision using the given function.
 * @method        CarbonInterface  floorMonth(float $precision = 1)                                                   Truncate the current instance month with given precision.
 * @method        CarbonInterface  floorMonths(float $precision = 1)                                                  Truncate the current instance month with given precision.
 * @method        CarbonInterface  ceilMonth(float $precision = 1)                                                    Ceil the current instance month with given precision.
 * @method        CarbonInterface  ceilMonths(float $precision = 1)                                                   Ceil the current instance month with given precision.
 * @method        CarbonInterface  roundDay(float $precision = 1, string $function = "round")                         Round the current instance day with given precision using the given function.
 * @method        CarbonInterface  roundDays(float $precision = 1, string $function = "round")                        Round the current instance day with given precision using the given function.
 * @method        CarbonInterface  floorDay(float $precision = 1)                                                     Truncate the current instance day with given precision.
 * @method        CarbonInterface  floorDays(float $precision = 1)                                                    Truncate the current instance day with given precision.
 * @method        CarbonInterface  ceilDay(float $precision = 1)                                                      Ceil the current instance day with given precision.
 * @method        CarbonInterface  ceilDays(float $precision = 1)                                                     Ceil the current instance day with given precision.
 * @method        CarbonInterface  roundHour(float $precision = 1, string $function = "round")                        Round the current instance hour with given precision using the given function.
 * @method        CarbonInterface  roundHours(float $precision = 1, string $function = "round")                       Round the current instance hour with given precision using the given function.
 * @method        CarbonInterface  floorHour(float $precision = 1)                                                    Truncate the current instance hour with given precision.
 * @method        CarbonInterface  floorHours(float $precision = 1)                                                   Truncate the current instance hour with given precision.
 * @method        CarbonInterface  ceilHour(float $precision = 1)                                                     Ceil the current instance hour with given precision.
 * @method        CarbonInterface  ceilHours(float $precision = 1)                                                    Ceil the current instance hour with given precision.
 * @method        CarbonInterface  roundMinute(float $precision = 1, string $function = "round")                      Round the current instance minute with given precision using the given function.
 * @method        CarbonInterface  roundMinutes(float $precision = 1, string $function = "round")                     Round the current instance minute with given precision using the given function.
 * @method        CarbonInterface  floorMinute(float $precision = 1)                                                  Truncate the current instance minute with given precision.
 * @method        CarbonInterface  floorMinutes(float $precision = 1)                                                 Truncate the current instance minute with given precision.
 * @method        CarbonInterface  ceilMinute(float $precision = 1)                                                   Ceil the current instance minute with given precision.
 * @method        CarbonInterface  ceilMinutes(float $precision = 1)                                                  Ceil the current instance minute with given precision.
 * @method        CarbonInterface  roundSecond(float $precision = 1, string $function = "round")                      Round the current instance second with given precision using the given function.
 * @method        CarbonInterface  roundSeconds(float $precision = 1, string $function = "round")                     Round the current instance second with given precision using the given function.
 * @method        CarbonInterface  floorSecond(float $precision = 1)                                                  Truncate the current instance second with given precision.
 * @method        CarbonInterface  floorSeconds(float $precision = 1)                                                 Truncate the current instance second with given precision.
 * @method        CarbonInterface  ceilSecond(float $precision = 1)                                                   Ceil the current instance second with given precision.
 * @method        CarbonInterface  ceilSeconds(float $precision = 1)                                                  Ceil the current instance second with given precision.
 * @method        CarbonInterface  roundMillennium(float $precision = 1, string $function = "round")                  Round the current instance millennium with given precision using the given function.
 * @method        CarbonInterface  roundMillennia(float $precision = 1, string $function = "round")                   Round the current instance millennium with given precision using the given function.
 * @method        CarbonInterface  floorMillennium(float $precision = 1)                                              Truncate the current instance millennium with given precision.
 * @method        CarbonInterface  floorMillennia(float $precision = 1)                                               Truncate the current instance millennium with given precision.
 * @method        CarbonInterface  ceilMillennium(float $precision = 1)                                               Ceil the current instance millennium with given precision.
 * @method        CarbonInterface  ceilMillennia(float $precision = 1)                                                Ceil the current instance millennium with given precision.
 * @method        CarbonInterface  roundCentury(float $precision = 1, string $function = "round")                     Round the current instance century with given precision using the given function.
 * @method        CarbonInterface  roundCenturies(float $precision = 1, string $function = "round")                   Round the current instance century with given precision using the given function.
 * @method        CarbonInterface  floorCentury(float $precision = 1)                                                 Truncate the current instance century with given precision.
 * @method        CarbonInterface  floorCenturies(float $precision = 1)                                               Truncate the current instance century with given precision.
 * @method        CarbonInterface  ceilCentury(float $precision = 1)                                                  Ceil the current instance century with given precision.
 * @method        CarbonInterface  ceilCenturies(float $precision = 1)                                                Ceil the current instance century with given precision.
 * @method        CarbonInterface  roundDecade(float $precision = 1, string $function = "round")                      Round the current instance decade with given precision using the given function.
 * @method        CarbonInterface  roundDecades(float $precision = 1, string $function = "round")                     Round the current instance decade with given precision using the given function.
 * @method        CarbonInterface  floorDecade(float $precision = 1)                                                  Truncate the current instance decade with given precision.
 * @method        CarbonInterface  floorDecades(float $precision = 1)                                                 Truncate the current instance decade with given precision.
 * @method        CarbonInterface  ceilDecade(float $precision = 1)                                                   Ceil the current instance decade with given precision.
 * @method        CarbonInterface  ceilDecades(float $precision = 1)                                                  Ceil the current instance decade with given precision.
 * @method        CarbonInterface  roundQuarter(float $precision = 1, string $function = "round")                     Round the current instance quarter with given precision using the given function.
 * @method        CarbonInterface  roundQuarters(float $precision = 1, string $function = "round")                    Round the current instance quarter with given precision using the given function.
 * @method        CarbonInterface  floorQuarter(float $precision = 1)                                                 Truncate the current instance quarter with given precision.
 * @method        CarbonInterface  floorQuarters(float $precision = 1)                                                Truncate the current instance quarter with given precision.
 * @method        CarbonInterface  ceilQuarter(float $precision = 1)                                                  Ceil the current instance quarter with given precision.
 * @method        CarbonInterface  ceilQuarters(float $precision = 1)                                                 Ceil the current instance quarter with given precision.
 * @method        CarbonInterface  roundMillisecond(float $precision = 1, string $function = "round")                 Round the current instance millisecond with given precision using the given function.
 * @method        CarbonInterface  roundMilliseconds(float $precision = 1, string $function = "round")                Round the current instance millisecond with given precision using the given function.
 * @method        CarbonInterface  floorMillisecond(float $precision = 1)                                             Truncate the current instance millisecond with given precision.
 * @method        CarbonInterface  floorMilliseconds(float $precision = 1)                                            Truncate the current instance millisecond with given precision.
 * @method        CarbonInterface  ceilMillisecond(float $precision = 1)                                              Ceil the current instance millisecond with given precision.
 * @method        CarbonInterface  ceilMilliseconds(float $precision = 1)                                             Ceil the current instance millisecond with given precision.
 * @method        CarbonInterface  roundMicrosecond(float $precision = 1, string $function = "round")                 Round the current instance microsecond with given precision using the given function.
 * @method        CarbonInterface  roundMicroseconds(float $precision = 1, string $function = "round")                Round the current instance microsecond with given precision using the given function.
 * @method        CarbonInterface  floorMicrosecond(float $precision = 1)                                             Truncate the current instance microsecond with given precision.
 * @method        CarbonInterface  floorMicroseconds(float $precision = 1)                                            Truncate the current instance microsecond with given precision.
 * @method        CarbonInterface  ceilMicrosecond(float $precision = 1)                                              Ceil the current instance microsecond with given precision.
 * @method        CarbonInterface  ceilMicroseconds(float $precision = 1)                                             Ceil the current instance microsecond with given precision.
 * @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.)
 * @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.)
 * @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.)
 * @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.)
 * @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.)
 * @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.)
 * @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.)
 * @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.)
 * @method        int              centuriesInMillennium()                                                            Return the number of centuries contained in the current millennium
 * @method        int|static       centuryOfMillennium(?int $century = null)                                          Return the value of the century starting from the beginning of the current millennium when called with no parameters, change the current century when called with an integer value
 * @method        int|static       dayOfCentury(?int $day = null)                                                     Return the value of the day starting from the beginning of the current century when called with no parameters, change the current day when called with an integer value
 * @method        int|static       dayOfDecade(?int $day = null)                                                      Return the value of the day starting from the beginning of the current decade when called with no parameters, change the current day when called with an integer value
 * @method        int|static       dayOfMillennium(?int $day = null)                                                  Return the value of the day starting from the beginning of the current millennium when called with no parameters, change the current day when called with an integer value
 * @method        int|static       dayOfMonth(?int $day = null)                                                       Return the value of the day starting from the beginning of the current month when called with no parameters, change the current day when called with an integer value
 * @method        int|static       dayOfQuarter(?int $day = null)                                                     Return the value of the day starting from the beginning of the current quarter when called with no parameters, change the current day when called with an integer value
 * @method        int|static       dayOfWeek(?int $day = null)                                                        Return the value of the day starting from the beginning of the current week when called with no parameters, change the current day when called with an integer value
 * @method        int              daysInCentury()                                                                    Return the number of days contained in the current century
 * @method        int              daysInDecade()                                                                     Return the number of days contained in the current decade
 * @method        int              daysInMillennium()                                                                 Return the number of days contained in the current millennium
 * @method        int              daysInMonth()                                                                      Return the number of days contained in the current month
 * @method        int              daysInQuarter()                                                                    Return the number of days contained in the current quarter
 * @method        int              daysInWeek()                                                                       Return the number of days contained in the current week
 * @method        int              daysInYear()                                                                       Return the number of days contained in the current year
 * @method        int|static       decadeOfCentury(?int $decade = null)                                               Return the value of the decade starting from the beginning of the current century when called with no parameters, change the current decade when called with an integer value
 * @method        int|static       decadeOfMillennium(?int $decade = null)                                            Return the value of the decade starting from the beginning of the current millennium when called with no parameters, change the current decade when called with an integer value
 * @method        int              decadesInCentury()                                                                 Return the number of decades contained in the current century
 * @method        int              decadesInMillennium()                                                              Return the number of decades contained in the current millennium
 * @method        int|static       hourOfCentury(?int $hour = null)                                                   Return the value of the hour starting from the beginning of the current century when called with no parameters, change the current hour when called with an integer value
 * @method        int|static       hourOfDay(?int $hour = null)                                                       Return the value of the hour starting from the beginning of the current day when called with no parameters, change the current hour when called with an integer value
 * @method        int|static       hourOfDecade(?int $hour = null)                                                    Return the value of the hour starting from the beginning of the current decade when called with no parameters, change the current hour when called with an integer value
 * @method        int|static       hourOfMillennium(?int $hour = null)                                                Return the value of the hour starting from the beginning of the current millennium when called with no parameters, change the current hour when called with an integer value
 * @method        int|static       hourOfMonth(?int $hour = null)                                                     Return the value of the hour starting from the beginning of the current month when called with no parameters, change the current hour when called with an integer value
 * @method        int|static       hourOfQuarter(?int $hour = null)                                                   Return the value of the hour starting from the beginning of the current quarter when called with no parameters, change the current hour when called with an integer value
 * @method        int|static       hourOfWeek(?int $hour = null)                                                      Return the value of the hour starting from the beginning of the current week when called with no parameters, change the current hour when called with an integer value
 * @method        int|static       hourOfYear(?int $hour = null)                                                      Return the value of the hour starting from the beginning of the current year when called with no parameters, change the current hour when called with an integer value
 * @method        int              hoursInCentury()                                                                   Return the number of hours contained in the current century
 * @method        int              hoursInDay()                                                                       Return the number of hours contained in the current day
 * @method        int              hoursInDecade()                                                                    Return the number of hours contained in the current decade
 * @method        int              hoursInMillennium()                                                                Return the number of hours contained in the current millennium
 * @method        int              hoursInMonth()                                                                     Return the number of hours contained in the current month
 * @method        int              hoursInQuarter()                                                                   Return the number of hours contained in the current quarter
 * @method        int              hoursInWeek()                                                                      Return the number of hours contained in the current week
 * @method        int              hoursInYear()                                                                      Return the number of hours contained in the current year
 * @method        int|static       microsecondOfCentury(?int $microsecond = null)                                     Return the value of the microsecond starting from the beginning of the current century when called with no parameters, change the current microsecond when called with an integer value
 * @method        int|static       microsecondOfDay(?int $microsecond = null)                                         Return the value of the microsecond starting from the beginning of the current day when called with no parameters, change the current microsecond when called with an integer value
 * @method        int|static       microsecondOfDecade(?int $microsecond = null)                                      Return the value of the microsecond starting from the beginning of the current decade when called with no parameters, change the current microsecond when called with an integer value
 * @method        int|static       microsecondOfHour(?int $microsecond = null)                                        Return the value of the microsecond starting from the beginning of the current hour when called with no parameters, change the current microsecond when called with an integer value
 * @method        int|static       microsecondOfMillennium(?int $microsecond = null)                                  Return the value of the microsecond starting from the beginning of the current millennium when called with no parameters, change the current microsecond when called with an integer value
 * @method        int|static       microsecondOfMillisecond(?int $microsecond = null)                                 Return the value of the microsecond starting from the beginning of the current millisecond when called with no parameters, change the current microsecond when called with an integer value
 * @method        int|static       microsecondOfMinute(?int $microsecond = null)                                      Return the value of the microsecond starting from the beginning of the current minute when called with no parameters, change the current microsecond when called with an integer value
 * @method        int|static       microsecondOfMonth(?int $microsecond = null)                                       Return the value of the microsecond starting from the beginning of the current month when called with no parameters, change the current microsecond when called with an integer value
 * @method        int|static       microsecondOfQuarter(?int $microsecond = null)                                     Return the value of the microsecond starting from the beginning of the current quarter when called with no parameters, change the current microsecond when called with an integer value
 * @method        int|static       microsecondOfSecond(?int $microsecond = null)                                      Return the value of the microsecond starting from the beginning of the current second when called with no parameters, change the current microsecond when called with an integer value
 * @method        int|static       microsecondOfWeek(?int $microsecond = null)                                        Return the value of the microsecond starting from the beginning of the current week when called with no parameters, change the current microsecond when called with an integer value
 * @method        int|static       microsecondOfYear(?int $microsecond = null)                                        Return the value of the microsecond starting from the beginning of the current year when called with no parameters, change the current microsecond when called with an integer value
 * @method        int              microsecondsInCentury()                                                            Return the number of microseconds contained in the current century
 * @method        int              microsecondsInDay()                                                                Return the number of microseconds contained in the current day
 * @method        int              microsecondsInDecade()                                                             Return the number of microseconds contained in the current decade
 * @method        int              microsecondsInHour()                                                               Return the number of microseconds contained in the current hour
 * @method        int              microsecondsInMillennium()                                                         Return the number of microseconds contained in the current millennium
 * @method        int              microsecondsInMillisecond()                                                        Return the number of microseconds contained in the current millisecond
 * @method        int              microsecondsInMinute()                                                             Return the number of microseconds contained in the current minute
 * @method        int              microsecondsInMonth()                                                              Return the number of microseconds contained in the current month
 * @method        int              microsecondsInQuarter()                                                            Return the number of microseconds contained in the current quarter
 * @method        int              microsecondsInSecond()                                                             Return the number of microseconds contained in the current second
 * @method        int              microsecondsInWeek()                                                               Return the number of microseconds contained in the current week
 * @method        int              microsecondsInYear()                                                               Return the number of microseconds contained in the current year
 * @method        int|static       millisecondOfCentury(?int $millisecond = null)                                     Return the value of the millisecond starting from the beginning of the current century when called with no parameters, change the current millisecond when called with an integer value
 * @method        int|static       millisecondOfDay(?int $millisecond = null)                                         Return the value of the millisecond starting from the beginning of the current day when called with no parameters, change the current millisecond when called with an integer value
 * @method        int|static       millisecondOfDecade(?int $millisecond = null)                                      Return the value of the millisecond starting from the beginning of the current decade when called with no parameters, change the current millisecond when called with an integer value
 * @method        int|static       millisecondOfHour(?int $millisecond = null)                                        Return the value of the millisecond starting from the beginning of the current hour when called with no parameters, change the current millisecond when called with an integer value
 * @method        int|static       millisecondOfMillennium(?int $millisecond = null)                                  Return the value of the millisecond starting from the beginning of the current millennium when called with no parameters, change the current millisecond when called with an integer value
 * @method        int|static       millisecondOfMinute(?int $millisecond = null)                                      Return the value of the millisecond starting from the beginning of the current minute when called with no parameters, change the current millisecond when called with an integer value
 * @method        int|static       millisecondOfMonth(?int $millisecond = null)                                       Return the value of the millisecond starting from the beginning of the current month when called with no parameters, change the current millisecond when called with an integer value
 * @method        int|static       millisecondOfQuarter(?int $millisecond = null)                                     Return the value of the millisecond starting from the beginning of the current quarter when called with no parameters, change the current millisecond when called with an integer value
 * @method        int|static       millisecondOfSecond(?int $millisecond = null)                                      Return the value of the millisecond starting from the beginning of the current second when called with no parameters, change the current millisecond when called with an integer value
 * @method        int|static       millisecondOfWeek(?int $millisecond = null)                                        Return the value of the millisecond starting from the beginning of the current week when called with no parameters, change the current millisecond when called with an integer value
 * @method        int|static       millisecondOfYear(?int $millisecond = null)                                        Return the value of the millisecond starting from the beginning of the current year when called with no parameters, change the current millisecond when called with an integer value
 * @method        int              millisecondsInCentury()                                                            Return the number of milliseconds contained in the current century
 * @method        int              millisecondsInDay()                                                                Return the number of milliseconds contained in the current day
 * @method        int              millisecondsInDecade()                                                             Return the number of milliseconds contained in the current decade
 * @method        int              millisecondsInHour()                                                               Return the number of milliseconds contained in the current hour
 * @method        int              millisecondsInMillennium()                                                         Return the number of milliseconds contained in the current millennium
 * @method        int              millisecondsInMinute()                                                             Return the number of milliseconds contained in the current minute
 * @method        int              millisecondsInMonth()                                                              Return the number of milliseconds contained in the current month
 * @method        int              millisecondsInQuarter()                                                            Return the number of milliseconds contained in the current quarter
 * @method        int              millisecondsInSecond()                                                             Return the number of milliseconds contained in the current second
 * @method        int              millisecondsInWeek()                                                               Return the number of milliseconds contained in the current week
 * @method        int              millisecondsInYear()                                                               Return the number of milliseconds contained in the current year
 * @method        int|static       minuteOfCentury(?int $minute = null)                                               Return the value of the minute starting from the beginning of the current century when called with no parameters, change the current minute when called with an integer value
 * @method        int|static       minuteOfDay(?int $minute = null)                                                   Return the value of the minute starting from the beginning of the current day when called with no parameters, change the current minute when called with an integer value
 * @method        int|static       minuteOfDecade(?int $minute = null)                                                Return the value of the minute starting from the beginning of the current decade when called with no parameters, change the current minute when called with an integer value
 * @method        int|static       minuteOfHour(?int $minute = null)                                                  Return the value of the minute starting from the beginning of the current hour when called with no parameters, change the current minute when called with an integer value
 * @method        int|static       minuteOfMillennium(?int $minute = null)                                            Return the value of the minute starting from the beginning of the current millennium when called with no parameters, change the current minute when called with an integer value
 * @method        int|static       minuteOfMonth(?int $minute = null)                                                 Return the value of the minute starting from the beginning of the current month when called with no parameters, change the current minute when called with an integer value
 * @method        int|static       minuteOfQuarter(?int $minute = null)                                               Return the value of the minute starting from the beginning of the current quarter when called with no parameters, change the current minute when called with an integer value
 * @method        int|static       minuteOfWeek(?int $minute = null)                                                  Return the value of the minute starting from the beginning of the current week when called with no parameters, change the current minute when called with an integer value
 * @method        int|static       minuteOfYear(?int $minute = null)                                                  Return the value of the minute starting from the beginning of the current year when called with no parameters, change the current minute when called with an integer value
 * @method        int              minutesInCentury()                                                                 Return the number of minutes contained in the current century
 * @method        int              minutesInDay()                                                                     Return the number of minutes contained in the current day
 * @method        int              minutesInDecade()                                                                  Return the number of minutes contained in the current decade
 * @method        int              minutesInHour()                                                                    Return the number of minutes contained in the current hour
 * @method        int              minutesInMillennium()                                                              Return the number of minutes contained in the current millennium
 * @method        int              minutesInMonth()                                                                   Return the number of minutes contained in the current month
 * @method        int              minutesInQuarter()                                                                 Return the number of minutes contained in the current quarter
 * @method        int              minutesInWeek()                                                                    Return the number of minutes contained in the current week
 * @method        int              minutesInYear()                                                                    Return the number of minutes contained in the current year
 * @method        int|static       monthOfCentury(?int $month = null)                                                 Return the value of the month starting from the beginning of the current century when called with no parameters, change the current month when called with an integer value
 * @method        int|static       monthOfDecade(?int $month = null)                                                  Return the value of the month starting from the beginning of the current decade when called with no parameters, change the current month when called with an integer value
 * @method        int|static       monthOfMillennium(?int $month = null)                                              Return the value of the month starting from the beginning of the current millennium when called with no parameters, change the current month when called with an integer value
 * @method        int|static       monthOfQuarter(?int $month = null)                                                 Return the value of the month starting from the beginning of the current quarter when called with no parameters, change the current month when called with an integer value
 * @method        int|static       monthOfYear(?int $month = null)                                                    Return the value of the month starting from the beginning of the current year when called with no parameters, change the current month when called with an integer value
 * @method        int              monthsInCentury()                                                                  Return the number of months contained in the current century
 * @method        int              monthsInDecade()                                                                   Return the number of months contained in the current decade
 * @method        int              monthsInMillennium()                                                               Return the number of months contained in the current millennium
 * @method        int              monthsInQuarter()                                                                  Return the number of months contained in the current quarter
 * @method        int              monthsInYear()                                                                     Return the number of months contained in the current year
 * @method        int|static       quarterOfCentury(?int $quarter = null)                                             Return the value of the quarter starting from the beginning of the current century when called with no parameters, change the current quarter when called with an integer value
 * @method        int|static       quarterOfDecade(?int $quarter = null)                                              Return the value of the quarter starting from the beginning of the current decade when called with no parameters, change the current quarter when called with an integer value
 * @method        int|static       quarterOfMillennium(?int $quarter = null)                                          Return the value of the quarter starting from the beginning of the current millennium when called with no parameters, change the current quarter when called with an integer value
 * @method        int|static       quarterOfYear(?int $quarter = null)                                                Return the value of the quarter starting from the beginning of the current year when called with no parameters, change the current quarter when called with an integer value
 * @method        int              quartersInCentury()                                                                Return the number of quarters contained in the current century
 * @method        int              quartersInDecade()                                                                 Return the number of quarters contained in the current decade
 * @method        int              quartersInMillennium()                                                             Return the number of quarters contained in the current millennium
 * @method        int              quartersInYear()                                                                   Return the number of quarters contained in the current year
 * @method        int|static       secondOfCentury(?int $second = null)                                               Return the value of the second starting from the beginning of the current century when called with no parameters, change the current second when called with an integer value
 * @method        int|static       secondOfDay(?int $second = null)                                                   Return the value of the second starting from the beginning of the current day when called with no parameters, change the current second when called with an integer value
 * @method        int|static       secondOfDecade(?int $second = null)                                                Return the value of the second starting from the beginning of the current decade when called with no parameters, change the current second when called with an integer value
 * @method        int|static       secondOfHour(?int $second = null)                                                  Return the value of the second starting from the beginning of the current hour when called with no parameters, change the current second when called with an integer value
 * @method        int|static       secondOfMillennium(?int $second = null)                                            Return the value of the second starting from the beginning of the current millennium when called with no parameters, change the current second when called with an integer value
 * @method        int|static       secondOfMinute(?int $second = null)                                                Return the value of the second starting from the beginning of the current minute when called with no parameters, change the current second when called with an integer value
 * @method        int|static       secondOfMonth(?int $second = null)                                                 Return the value of the second starting from the beginning of the current month when called with no parameters, change the current second when called with an integer value
 * @method        int|static       secondOfQuarter(?int $second = null)                                               Return the value of the second starting from the beginning of the current quarter when called with no parameters, change the current second when called with an integer value
 * @method        int|static       secondOfWeek(?int $second = null)                                                  Return the value of the second starting from the beginning of the current week when called with no parameters, change the current second when called with an integer value
 * @method        int|static       secondOfYear(?int $second = null)                                                  Return the value of the second starting from the beginning of the current year when called with no parameters, change the current second when called with an integer value
 * @method        int              secondsInCentury()                                                                 Return the number of seconds contained in the current century
 * @method        int              secondsInDay()                                                                     Return the number of seconds contained in the current day
 * @method        int              secondsInDecade()                                                                  Return the number of seconds contained in the current decade
 * @method        int              secondsInHour()                                                                    Return the number of seconds contained in the current hour
 * @method        int              secondsInMillennium()                                                              Return the number of seconds contained in the current millennium
 * @method        int              secondsInMinute()                                                                  Return the number of seconds contained in the current minute
 * @method        int              secondsInMonth()                                                                   Return the number of seconds contained in the current month
 * @method        int              secondsInQuarter()                                                                 Return the number of seconds contained in the current quarter
 * @method        int              secondsInWeek()                                                                    Return the number of seconds contained in the current week
 * @method        int              secondsInYear()                                                                    Return the number of seconds contained in the current year
 * @method        int|static       weekOfCentury(?int $week = null)                                                   Return the value of the week starting from the beginning of the current century when called with no parameters, change the current week when called with an integer value
 * @method        int|static       weekOfDecade(?int $week = null)                                                    Return the value of the week starting from the beginning of the current decade when called with no parameters, change the current week when called with an integer value
 * @method        int|static       weekOfMillennium(?int $week = null)                                                Return the value of the week starting from the beginning of the current millennium when called with no parameters, change the current week when called with an integer value
 * @method        int|static       weekOfMonth(?int $week = null)                                                     Return the value of the week starting from the beginning of the current month when called with no parameters, change the current week when called with an integer value
 * @method        int|static       weekOfQuarter(?int $week = null)                                                   Return the value of the week starting from the beginning of the current quarter when called with no parameters, change the current week when called with an integer value
 * @method        int|static       weekOfYear(?int $week = null)                                                      Return the value of the week starting from the beginning of the current year when called with no parameters, change the current week when called with an integer value
 * @method        int              weeksInCentury()                                                                   Return the number of weeks contained in the current century
 * @method        int              weeksInDecade()                                                                    Return the number of weeks contained in the current decade
 * @method        int              weeksInMillennium()                                                                Return the number of weeks contained in the current millennium
 * @method        int              weeksInMonth()                                                                     Return the number of weeks contained in the current month
 * @method        int              weeksInQuarter()                                                                   Return the number of weeks contained in the current quarter
 * @method        int|static       yearOfCentury(?int $year = null)                                                   Return the value of the year starting from the beginning of the current century when called with no parameters, change the current year when called with an integer value
 * @method        int|static       yearOfDecade(?int $year = null)                                                    Return the value of the year starting from the beginning of the current decade when called with no parameters, change the current year when called with an integer value
 * @method        int|static       yearOfMillennium(?int $year = null)                                                Return the value of the year starting from the beginning of the current millennium when called with no parameters, change the current year when called with an integer value
 * @method        int              yearsInCentury()                                                                   Return the number of years contained in the current century
 * @method        int              yearsInDecade()                                                                    Return the number of years contained in the current decade
 * @method        int              yearsInMillennium()                                                                Return the number of years contained in the current millennium
 *
 * </autodoc>
 */
trait Date
{
    use Boundaries;
    use Comparison;
    use Converter;
    use Creator;
    use Difference;
    use Macro;
    use MagicParameter;
    use Modifiers;
    use Mutability;
    use ObjectInitialisation;
    use Options;
    use Rounding;
    use Serialization;
    use Test;
    use Timestamp;
    use Units;
    use Week;

    /**
     * Names of days of the week.
     *
     * @var array
     */
    protected static $days = [
        // @call isDayOfWeek
        CarbonInterface::SUNDAY => 'Sunday',
        // @call isDayOfWeek
        CarbonInterface::MONDAY => 'Monday',
        // @call isDayOfWeek
        CarbonInterface::TUESDAY => 'Tuesday',
        // @call isDayOfWeek
        CarbonInterface::WEDNESDAY => 'Wednesday',
        // @call isDayOfWeek
        CarbonInterface::THURSDAY => 'Thursday',
        // @call isDayOfWeek
        CarbonInterface::FRIDAY => 'Friday',
        // @call isDayOfWeek
        CarbonInterface::SATURDAY => 'Saturday',
    ];

    /**
     * List of unit and magic methods associated as doc-comments.
     *
     * @var array
     */
    protected static $units = [
        // @call setUnit
        // @call addUnit
        'year',
        // @call setUnit
        // @call addUnit
        'month',
        // @call setUnit
        // @call addUnit
        'day',
        // @call setUnit
        // @call addUnit
        'hour',
        // @call setUnit
        // @call addUnit
        'minute',
        // @call setUnit
        // @call addUnit
        'second',
        // @call setUnit
        // @call addUnit
        'milli',
        // @call setUnit
        // @call addUnit
        'millisecond',
        // @call setUnit
        // @call addUnit
        'micro',
        // @call setUnit
        // @call addUnit
        'microsecond',
    ];

    /**
     * Creates a DateTimeZone from a string, DateTimeZone or integer offset.
     *
     * @param DateTimeZone|string|int|false|null $object     original value to get CarbonTimeZone from it.
     * @param DateTimeZone|string|int|false|null $objectDump dump of the object for error messages.
     *
     * @throws InvalidTimeZoneException
     *
     * @return CarbonTimeZone|null
     */
    protected static function safeCreateDateTimeZone(
        DateTimeZone|string|int|false|null $object,
        DateTimeZone|string|int|false|null $objectDump = null,
    ): ?CarbonTimeZone {
        return CarbonTimeZone::instance($object, $objectDump);
    }

    /**
     * Get the TimeZone associated with the Carbon instance (as CarbonTimeZone).
     *
     * @link https://php.net/manual/en/datetime.gettimezone.php
     */
    public function getTimezone(): CarbonTimeZone
    {
        return $this->transmitFactory(fn () => CarbonTimeZone::instance(parent::getTimezone()));
    }

    /**
     * List of minimum and maximums for each unit.
     */
    protected static function getRangesByUnit(int $daysInMonth = 31): array
    {
        return [
            // @call roundUnit
            'year' => [1, 9999],
            // @call roundUnit
            'month' => [1, static::MONTHS_PER_YEAR],
            // @call roundUnit
            'day' => [1, $daysInMonth],
            // @call roundUnit
            'hour' => [0, static::HOURS_PER_DAY - 1],
            // @call roundUnit
            'minute' => [0, static::MINUTES_PER_HOUR - 1],
            // @call roundUnit
            'second' => [0, static::SECONDS_PER_MINUTE - 1],
        ];
    }

    /**
     * Get a copy of the instance.
     *
     * @return static
     */
    public function copy()
    {
        return clone $this;
    }

    /**
     * @alias copy
     *
     * Get a copy of the instance.
     *
     * @return static
     */
    public function clone()
    {
        return clone $this;
    }

    /**
     * Clone the current instance if it's mutable.
     *
     * This method is convenient to ensure you don't mutate the initial object
     * but avoid to make a useless copy of it if it's already immutable.
     *
     * @return static
     */
    public function avoidMutation(): static
    {
        if ($this instanceof DateTimeImmutable) {
            return $this;
        }

        return clone $this;
    }

    /**
     * Returns a present instance in the same timezone.
     *
     * @return static
     */
    public function nowWithSameTz(): static
    {
        $timezone = $this->getTimezone();

        return $this->getClock()?->nowAs(static::class, $timezone) ?? static::now($timezone);
    }

    /**
     * Return the Carbon instance passed through, a now instance in the same timezone
     * if null given or parse the input if string given.
     *
     * @param Carbon|\Carbon\CarbonPeriod|\Carbon\CarbonInterval|\DateInterval|\DatePeriod|DateTimeInterface|string|null $date
     *
     * @return static
     */
    public function carbonize($date = null)
    {
        if ($date instanceof DateInterval) {
            return $this->avoidMutation()->add($date);
        }

        if ($date instanceof DatePeriod || $date instanceof CarbonPeriod) {
            $date = $date->getStartDate();
        }

        return $this->resolveCarbon($date);
    }

    ///////////////////////////////////////////////////////////////////
    ///////////////////////// GETTERS AND SETTERS /////////////////////
    ///////////////////////////////////////////////////////////////////

    /**
     * Get a part of the Carbon object.
     *
     * @throws UnknownGetterException
     *
     * @return string|int|bool|DateTimeZone|null
     */
    public function __get(string $name): mixed
    {
        return $this->get($name);
    }

    /**
     * Get a part of the Carbon object.
     *
     * @throws UnknownGetterException
     *
     * @return string|int|bool|DateTimeZone
     */
    public function get(Unit|string $name): mixed
    {
        static $localizedFormats = [
            // @property string the day of week in current locale
            'localeDayOfWeek' => 'dddd',
            // @property string the abbreviated day of week in current locale
            'shortLocaleDayOfWeek' => 'ddd',
            // @property string the month in current locale
            'localeMonth' => 'MMMM',
            // @property string the abbreviated month in current locale
            'shortLocaleMonth' => 'MMM',
        ];

        $name = Unit::toName($name);

        if (isset($localizedFormats[$name])) {
            return $this->isoFormat($localizedFormats[$name]);
        }

        static $formats = [
            // @property int
            'year' => 'Y',
            // @property int
            'yearIso' => 'o',
            // @--property-read int
            // @--property-write Month|int
            // @property int
            'month' => 'n',
            // @property int
            'day' => 'j',
            // @property int
            'hour' => 'G',
            // @property int
            'minute' => 'i',
            // @property int
            'second' => 's',
            // @property int
            'micro' => 'u',
            // @property int
            'microsecond' => 'u',
            // @property int 0 (for Sunday) through 6 (for Saturday)
            'dayOfWeek' => 'w',
            // @property int 1 (for Monday) through 7 (for Sunday)
            'dayOfWeekIso' => 'N',
            // @property int ISO-8601 week number of year, weeks starting on Monday
            'weekOfYear' => 'W',
            // @property-read int number of days in the given month
            'daysInMonth' => 't',
            // @property int|float|string seconds since the Unix Epoch
            'timestamp' => 'U',
            // @property-read string "am"/"pm" (Ante meridiem or Post meridiem latin lowercase mark)
            'latinMeridiem' => 'a',
            // @property-read string "AM"/"PM" (Ante meridiem or Post meridiem latin uppercase mark)
            'latinUpperMeridiem' => 'A',
            // @property string the day of week in English
            'englishDayOfWeek' => 'l',
            // @property string the abbreviated day of week in English
            'shortEnglishDayOfWeek' => 'D',
            // @property string the month in English
            'englishMonth' => 'F',
            // @property string the abbreviated month in English
            'shortEnglishMonth' => 'M',
            // @property-read string $timezoneAbbreviatedName the current timezone abbreviated name
            'timezoneAbbreviatedName' => 'T',
            // @property-read string $tzAbbrName alias of $timezoneAbbreviatedName
            'tzAbbrName' => 'T',
        ];

        switch (true) {
            case isset($formats[$name]):
                $value = $this->rawFormat($formats[$name]);

                return is_numeric($value) ? (int) $value : $value;

            // @property-read string long name of weekday translated according to Carbon locale, in english if no translation available for current language
            case $name === 'dayName':
                return $this->getTranslatedDayName();
            // @property-read string short name of weekday translated according to Carbon locale, in english if no translation available for current language
            case $name === 'shortDayName':
                return $this->getTranslatedShortDayName();
            // @property-read string very short name of weekday translated according to Carbon locale, in english if no translation available for current language
            case $name === 'minDayName':
                return $this->getTranslatedMinDayName();
            // @property-read string long name of month translated according to Carbon locale, in english if no translation available for current language
            case $name === 'monthName':
                return $this->getTranslatedMonthName();
            // @property-read string short name of month translated according to Carbon locale, in english if no translation available for current language
            case $name === 'shortMonthName':
                return $this->getTranslatedShortMonthName();
            // @property-read string lowercase meridiem mark translated according to Carbon locale, in latin if no translation available for current language
            case $name === 'meridiem':
                return $this->meridiem(true);
            // @property-read string uppercase meridiem mark translated according to Carbon locale, in latin if no translation available for current language
            case $name === 'upperMeridiem':
                return $this->meridiem();
            // @property-read int current hour from 1 to 24
            case $name === 'noZeroHour':
                return $this->hour ?: 24;
            // @property int
            case $name === 'milliseconds':
                // @property int
            case $name === 'millisecond':
            // @property int
            case $name === 'milli':
                return (int) floor(((int) $this->rawFormat('u')) / 1000);

            // @property int 1 through 53
            case $name === 'week':
                return (int) $this->week();

            // @property int 1 through 53
            case $name === 'isoWeek':
                return (int) $this->isoWeek();

            // @property int year according to week format
            case $name === 'weekYear':
                return (int) $this->weekYear();

            // @property int year according to ISO week format
            case $name === 'isoWeekYear':
                return (int) $this->isoWeekYear();

            // @property-read int 51 through 53
            case $name === 'weeksInYear':
                return $this->weeksInYear();

            // @property-read int 51 through 53
            case $name === 'isoWeeksInYear':
                return $this->isoWeeksInYear();

            // @property int 1 through 5
            case $name === 'weekOfMonth':
                return (int) ceil($this->day / static::DAYS_PER_WEEK);

            // @property-read int 1 through 5
            case $name === 'weekNumberInMonth':
                return (int) ceil(($this->day + $this->avoidMutation()->startOfMonth()->dayOfWeekIso - 1) / static::DAYS_PER_WEEK);

            // @property-read int 0 through 6
            case $name === 'firstWeekDay':
                return (int) $this->getTranslationMessage('first_day_of_week');

            // @property-read int 0 through 6
            case $name === 'lastWeekDay':
                return $this->transmitFactory(fn () => static::weekRotate((int) $this->getTranslationMessage('first_day_of_week'), -1));

            // @property int 1 through 366
            case $name === 'dayOfYear':
                return 1 + (int) ($this->rawFormat('z'));

            // @property-read int 365 or 366
            case $name === 'daysInYear':
                return static::DAYS_PER_YEAR + ($this->isLeapYear() ? 1 : 0);

            // @property int does a diffInYears() with default parameters
            case $name === 'age':
                return (int) $this->diffInYears();

            // @property-read int the quarter of this instance, 1 - 4
            case $name === 'quarter':
                return (int) ceil($this->month / static::MONTHS_PER_QUARTER);

            // @property-read int the decade of this instance
            // @call isSameUnit
            case $name === 'decade':
                return (int) ceil($this->year / static::YEARS_PER_DECADE);

            // @property-read int the century of this instance
            // @call isSameUnit
            case $name === 'century':
                $factor = 1;
                $year = $this->year;

                if ($year < 0) {
                    $year = -$year;
                    $factor = -1;
                }

                return (int) ($factor * ceil($year / static::YEARS_PER_CENTURY));

            // @property-read int the millennium of this instance
            // @call isSameUnit
            case $name === 'millennium':
                $factor = 1;
                $year = $this->year;

                if ($year < 0) {
                    $year = -$year;
                    $factor = -1;
                }

                return (int) ($factor * ceil($year / static::YEARS_PER_MILLENNIUM));

            // @property int the timezone offset in seconds from UTC
            case $name === 'offset':
                return $this->getOffset();

            // @property int the timezone offset in minutes from UTC
            case $name === 'offsetMinutes':
                return $this->getOffset() / static::SECONDS_PER_MINUTE;

            // @property int the timezone offset in hours from UTC
            case $name === 'offsetHours':
                return $this->getOffset() / static::SECONDS_PER_MINUTE / static::MINUTES_PER_HOUR;

            // @property-read bool daylight savings time indicator, true if DST, false otherwise
            case $name === 'dst':
                return $this->rawFormat('I') === '1';

            // @property-read bool checks if the timezone is local, true if local, false otherwise
            case $name === 'local':
                return $this->getOffset() === $this->avoidMutation()->setTimezone(date_default_timezone_get())->getOffset();

            // @property-read bool checks if the timezone is UTC, true if UTC, false otherwise
            case $name === 'utc':
                return $this->getOffset() === 0;

            // @--property-write DateTimeZone|string|int $timezone the current timezone
            // @--property-write DateTimeZone|string|int $tz alias of $timezone
            // @--property-read CarbonTimeZone $timezone the current timezone
            // @--property-read CarbonTimeZone $tz alias of $timezone
            // @property CarbonTimeZone $timezone the current timezone
            // @property CarbonTimeZone $tz alias of $timezone
            case $name === 'timezone' || $name === 'tz':
                return $this->getTimezone();

            // @property-read string $timezoneName the current timezone name
            // @property-read string $tzName alias of $timezoneName
            case $name === 'timezoneName' || $name === 'tzName':
                return $this->getTimezone()->getName();

            // @property-read string locale of the current instance
            case $name === 'locale':
                return $this->getTranslatorLocale();

            case preg_match('/^([a-z]{2,})(In|Of)([A-Z][a-z]+)$/', $name, $match):
                [, $firstUnit, $operator, $secondUnit] = $match;

                try {
                    $start = $this->avoidMutation()->startOf($secondUnit);
                    $value = $operator === 'Of'
                        ? (\in_array($firstUnit, [
                            // Unit with indexes starting at 1 (other units start at 0)
                            'day',
                            'week',
                            'month',
                            'quarter',
                        ], true) ? 1 : 0) + floor($start->diffInUnit($firstUnit, $this))
                        : round($start->diffInUnit($firstUnit, $start->avoidMutation()->add($secondUnit, 1)));

                    return (int) $value;
                } catch (UnknownUnitException) {
                    // default to macro
                }

            default:
                $macro = $this->getLocalMacro('get'.ucfirst($name));

                if ($macro) {
                    return $this->executeCallableWithContext($macro);
                }

                throw new UnknownGetterException($name);
        }
    }

    /**
     * Check if an attribute exists on the object
     *
     * @param string $name
     *
     * @return bool
     */
    public function __isset($name)
    {
        try {
            $this->__get($name);
        } catch (UnknownGetterException | ReflectionException) {
            return false;
        }

        return true;
    }

    /**
     * Set a part of the Carbon object
     *
     * @param string                  $name
     * @param string|int|DateTimeZone $value
     *
     * @throws UnknownSetterException|ReflectionException
     *
     * @return void
     */
    public function __set($name, $value)
    {
        if ($this->constructedObjectId === spl_object_hash($this)) {
            $this->set($name, $value);

            return;
        }

        $this->$name = $value;
    }

    /**
     * Set a part of the Carbon object.
     *
     * @throws ImmutableException|UnknownSetterException
     *
     * @return $this
     */
    public function set(Unit|array|string $name, DateTimeZone|Month|string|int|float|null $value = null): static
    {
        if ($this->isImmutable()) {
            throw new ImmutableException(\sprintf('%s class', static::class));
        }

        if (\is_array($name)) {
            foreach ($name as $key => $value) {
                $this->set($key, $value);
            }

            return $this;
        }

        $name = Unit::toName($name);

        switch ($name) {
            case 'milliseconds':
            case 'millisecond':
            case 'milli':
            case 'microseconds':
            case 'microsecond':
            case 'micro':
                if (str_starts_with($name, 'milli')) {
                    $value *= 1000;
                }

                while ($value < 0) {
                    $this->subSecond();
                    $value += static::MICROSECONDS_PER_SECOND;
                }

                while ($value >= static::MICROSECONDS_PER_SECOND) {
                    $this->addSecond();
                    $value -= static::MICROSECONDS_PER_SECOND;
                }

                $this->modify($this->rawFormat('H:i:s.').str_pad((string) round($value), 6, '0', STR_PAD_LEFT));

                break;

            case 'year':
            case 'month':
            case 'day':
            case 'hour':
            case 'minute':
            case 'second':
                [$year, $month, $day, $hour, $minute, $second] = array_map('intval', explode('-', $this->rawFormat('Y-n-j-G-i-s')));
                $$name = self::monthToInt($value, $name);
                $this->setDateTime($year, $month, $day, $hour, $minute, $second);

                break;

            case 'week':
                $this->week($value);

                break;

            case 'isoWeek':
                $this->isoWeek($value);

                break;

            case 'weekYear':
                $this->weekYear($value);

                break;

            case 'isoWeekYear':
                $this->isoWeekYear($value);

                break;

            case 'dayOfYear':
                $this->addDays($value - $this->dayOfYear);

                break;

            case 'dayOfWeek':
                $this->addDays($value - $this->dayOfWeek);

                break;

            case 'dayOfWeekIso':
                $this->addDays($value - $this->dayOfWeekIso);

                break;

            case 'timestamp':
                $this->setTimestamp($value);

                break;

            case 'offset':
                $this->setTimezone(static::safeCreateDateTimeZone($value / static::SECONDS_PER_MINUTE / static::MINUTES_PER_HOUR));

                break;

            case 'offsetMinutes':
                $this->setTimezone(static::safeCreateDateTimeZone($value / static::MINUTES_PER_HOUR));

                break;

            case 'offsetHours':
                $this->setTimezone(static::safeCreateDateTimeZone($value));

                break;

            case 'timezone':
            case 'tz':
                $this->setTimezone($value);

                break;

            default:
                if (preg_match('/^([a-z]{2,})Of([A-Z][a-z]+)$/', $name, $match)) {
                    [, $firstUnit, $secondUnit] = $match;

                    try {
                        $start = $this->avoidMutation()->startOf($secondUnit);
                        $currentValue = (\in_array($firstUnit, [
                            // Unit with indexes starting at 1 (other units start at 0)
                            'day',
                            'week',
                            'month',
                            'quarter',
                        ], true) ? 1 : 0) + (int) floor($start->diffInUnit($firstUnit, $this));

                        // We check $value a posteriori to give precedence to UnknownUnitException
                        if (!\is_int($value)) {
                            throw new UnitException("->$name expects integer value");
                        }

                        $this->addUnit($firstUnit, $value - $currentValue);

                        break;
                    } catch (UnknownUnitException) {
                        // default to macro
                    }
                }

                $macro = $this->getLocalMacro('set'.ucfirst($name));

                if ($macro) {
                    $this->executeCallableWithContext($macro, $value);

                    break;
                }

                if ($this->isLocalStrictModeEnabled()) {
                    throw new UnknownSetterException($name);
                }

                $this->$name = $value;
        }

        return $this;
    }

    /**
     * Get the translation of the current week day name (with context for languages with multiple forms).
     *
     * @param string|null $context      whole format string
     * @param string      $keySuffix    "", "_short" or "_min"
     * @param string|null $defaultValue default value if translation missing
     */
    public function getTranslatedDayName(
        ?string $context = null,
        string $keySuffix = '',
        ?string $defaultValue = null,
    ): string {
        return $this->getTranslatedFormByRegExp('weekdays', $keySuffix, $context, $this->dayOfWeek, $defaultValue ?: $this->englishDayOfWeek);
    }

    /**
     * Get the translation of the current short week day name (with context for languages with multiple forms).
     *
     * @param string|null $context whole format string
     */
    public function getTranslatedShortDayName(?string $context = null): string
    {
        return $this->getTranslatedDayName($context, '_short', $this->shortEnglishDayOfWeek);
    }

    /**
     * Get the translation of the current abbreviated week day name (with context for languages with multiple forms).
     *
     * @param string|null $context whole format string
     */
    public function getTranslatedMinDayName(?string $context = null): string
    {
        return $this->getTranslatedDayName($context, '_min', $this->shortEnglishDayOfWeek);
    }

    /**
     * Get the translation of the current month day name (with context for languages with multiple forms).
     *
     * @param string|null $context      whole format string
     * @param string      $keySuffix    "" or "_short"
     * @param string|null $defaultValue default value if translation missing
     */
    public function getTranslatedMonthName(
        ?string $context = null,
        string $keySuffix = '',
        ?string $defaultValue = null,
    ): string {
        return $this->getTranslatedFormByRegExp('months', $keySuffix, $context, $this->month - 1, $defaultValue ?: $this->englishMonth);
    }

    /**
     * Get the translation of the current short month day name (with context for languages with multiple forms).
     *
     * @param string|null $context whole format string
     */
    public function getTranslatedShortMonthName(?string $context = null): string
    {
        return $this->getTranslatedMonthName($context, '_short', $this->shortEnglishMonth);
    }

    /**
     * Get/set the day of year.
     *
     * @template T of int|null
     *
     * @param int|null $value new value for day of year if using as setter.
     *
     * @psalm-param T $value
     *
     * @return static|int
     *
     * @psalm-return (T is int ? static : int)
     */
    public function dayOfYear(?int $value = null): static|int
    {
        $dayOfYear = $this->dayOfYear;

        return $value === null ? $dayOfYear : $this->addDays($value - $dayOfYear);
    }

    /**
     * Get/set the weekday from 0 (Sunday) to 6 (Saturday).
     *
     * @param WeekDay|int|null $value new value for weekday if using as setter.
     */
    public function weekday(WeekDay|int|null $value = null): static|int
    {
        if ($value === null) {
            return $this->dayOfWeek;
        }

        $firstDay = (int) ($this->getTranslationMessage('first_day_of_week') ?? 0);
        $dayOfWeek = ($this->dayOfWeek + 7 - $firstDay) % 7;

        return $this->addDays(((WeekDay::int($value) + 7 - $firstDay) % 7) - $dayOfWeek);
    }

    /**
     * Get/set the ISO weekday from 1 (Monday) to 7 (Sunday).
     *
     * @param WeekDay|int|null $value new value for weekday if using as setter.
     */
    public function isoWeekday(WeekDay|int|null $value = null): static|int
    {
        $dayOfWeekIso = $this->dayOfWeekIso;

        return $value === null ? $dayOfWeekIso : $this->addDays(WeekDay::int($value) - $dayOfWeekIso);
    }

    /**
     * Return the number of days since the start of the week (using the current locale or the first parameter
     * if explicitly given).
     *
     * @param WeekDay|int|null $weekStartsAt optional start allow you to specify the day of week to use to start the week,
     *                                       if not provided, start of week is inferred from the locale
     *                                       (Sunday for en_US, Monday for de_DE, etc.)
     */
    public function getDaysFromStartOfWeek(WeekDay|int|null $weekStartsAt = null): int
    {
        $firstDay = (int) (WeekDay::int($weekStartsAt) ?? $this->getTranslationMessage('first_day_of_week') ?? 0);

        return ($this->dayOfWeek + 7 - $firstDay) % 7;
    }

    /**
     * Set the day (keeping the current time) to the start of the week + the number of days passed as the first
     * parameter. First day of week is driven by the locale unless explicitly set with the second parameter.
     *
     * @param int              $numberOfDays number of days to add after the start of the current week
     * @param WeekDay|int|null $weekStartsAt optional start allow you to specify the day of week to use to start the week,
     *                                       if not provided, start of week is inferred from the locale
     *                                       (Sunday for en_US, Monday for de_DE, etc.)
     */
    public function setDaysFromStartOfWeek(int $numberOfDays, WeekDay|int|null $weekStartsAt = null): static
    {
        return $this->addDays($numberOfDays - $this->getDaysFromStartOfWeek(WeekDay::int($weekStartsAt)));
    }

    /**
     * Set any unit to a new value without overflowing current other unit given.
     *
     * @param string $valueUnit    unit name to modify
     * @param int    $value        new value for the input unit
     * @param string $overflowUnit unit name to not overflow
     */
    public function setUnitNoOverflow(string $valueUnit, int $value, string $overflowUnit): static
    {
        try {
            $start = $this->avoidMutation()->startOf($overflowUnit);
            $end = $this->avoidMutation()->endOf($overflowUnit);
            /** @var static $date */
            $date = $this->$valueUnit($value);

            if ($date < $start) {
                return $date->mutateIfMutable($start);
            }

            if ($date > $end) {
                return $date->mutateIfMutable($end);
            }

            return $date;
        } catch (BadMethodCallException | ReflectionException $exception) {
            throw new UnknownUnitException($valueUnit, 0, $exception);
        }
    }

    /**
     * Add any unit to a new value without overflowing current other unit given.
     *
     * @param string $valueUnit    unit name to modify
     * @param int    $value        amount to add to the input unit
     * @param string $overflowUnit unit name to not overflow
     */
    public function addUnitNoOverflow(string $valueUnit, int $value, string $overflowUnit): static
    {
        return $this->setUnitNoOverflow($valueUnit, $this->$valueUnit + $value, $overflowUnit);
    }

    /**
     * Subtract any unit to a new value without overflowing current other unit given.
     *
     * @param string $valueUnit    unit name to modify
     * @param int    $value        amount to subtract to the input unit
     * @param string $overflowUnit unit name to not overflow
     */
    public function subUnitNoOverflow(string $valueUnit, int $value, string $overflowUnit): static
    {
        return $this->setUnitNoOverflow($valueUnit, $this->$valueUnit - $value, $overflowUnit);
    }

    /**
     * Returns the minutes offset to UTC if no arguments passed, else set the timezone with given minutes shift passed.
     */
    public function utcOffset(?int $minuteOffset = null): static|int
    {
        if ($minuteOffset === null) {
            return $this->offsetMinutes;
        }

        return $this->setTimezone(CarbonTimeZone::createFromMinuteOffset($minuteOffset));
    }

    /**
     * Set the date with gregorian year, month and day numbers.
     *
     * @see https://php.net/manual/en/datetime.setdate.php
     */
    public function setDate(int $year, int $month, int $day): static
    {
        return parent::setDate($year, $month, $day);
    }

    /**
     * Set a date according to the ISO 8601 standard - using weeks and day offsets rather than specific dates.
     *
     * @see https://php.net/manual/en/datetime.setisodate.php
     */
    public function setISODate(int $year, int $week, int $day = 1): static
    {
        return parent::setISODate($year, $week, $day);
    }

    /**
     * Set the date and time all together.
     */
    public function setDateTime(
        int $year,
        int $month,
        int $day,
        int $hour,
        int $minute,
        int $second = 0,
        int $microseconds = 0,
    ): static {
        return $this->setDate($year, $month, $day)->setTime($hour, $minute, $second, $microseconds);
    }

    /**
     * Resets the current time of the DateTime object to a different time.
     *
     * @see https://php.net/manual/en/datetime.settime.php
     */
    public function setTime(int $hour, int $minute, int $second = 0, int $microseconds = 0): static
    {
        return parent::setTime($hour, $minute, $second, $microseconds);
    }

    /**
     * Set the instance's timestamp.
     *
     * Timestamp input can be given as int, float or a string containing one or more numbers.
     */
    public function setTimestamp(float|int|string $timestamp): static
    {
        [$seconds, $microseconds] = self::getIntegerAndDecimalParts($timestamp);

        return parent::setTimestamp((int) $seconds)->setMicroseconds((int) $microseconds);
    }

    /**
     * Set the time by time string.
     */
    public function setTimeFromTimeString(string $time): static
    {
        if (!str_contains($time, ':')) {
            $time .= ':0';
        }

        return $this->modify($time);
    }

    /**
     * @alias setTimezone
     */
    public function timezone(DateTimeZone|string|int $value): static
    {
        return $this->setTimezone($value);
    }

    /**
     * Set the timezone or returns the timezone name if no arguments passed.
     *
     * @return ($value is null ? string : static)
     */
    public function tz(DateTimeZone|string|int|null $value = null): static|string
    {
        if ($value === null) {
            return $this->tzName;
        }

        return $this->setTimezone($value);
    }

    /**
     * Set the instance's timezone from a string or object.
     */
    public function setTimezone(DateTimeZone|string|int $timeZone): static
    {
        return parent::setTimezone(static::safeCreateDateTimeZone($timeZone));
    }

    /**
     * Set the instance's timezone from a string or object and add/subtract the offset difference.
     */
    public function shiftTimezone(DateTimeZone|string $value): static
    {
        $dateTimeString = $this->format('Y-m-d H:i:s.u');

        return $this
            ->setTimezone($value)
            ->modify($dateTimeString);
    }

    /**
     * Set the instance's timezone to UTC.
     */
    public function utc(): static
    {
        return $this->setTimezone('UTC');
    }

    /**
     * Set the year, month, and date for this instance to that of the passed instance.
     */
    public function setDateFrom(DateTimeInterface|string $date): static
    {
        $date = $this->resolveCarbon($date);

        return $this->setDate($date->year, $date->month, $date->day);
    }

    /**
     * Set the hour, minute, second and microseconds for this instance to that of the passed instance.
     */
    public function setTimeFrom(DateTimeInterface|string $date): static
    {
        $date = $this->resolveCarbon($date);

        return $this->setTime($date->hour, $date->minute, $date->second, $date->microsecond);
    }

    /**
     * Set the date and time for this instance to that of the passed instance.
     */
    public function setDateTimeFrom(DateTimeInterface|string $date): static
    {
        $date = $this->resolveCarbon($date);

        return $this->modify($date->rawFormat('Y-m-d H:i:s.u'));
    }

    /**
     * Get the days of the week.
     */
    public static function getDays(): array
    {
        return static::$days;
    }

    ///////////////////////////////////////////////////////////////////
    /////////////////////// WEEK SPECIAL DAYS /////////////////////////
    ///////////////////////////////////////////////////////////////////

    /**
     * Get the first day of week.
     *
     * @return int
     */
    public static function getWeekStartsAt(?string $locale = null): int
    {
        return (int) static::getTranslationMessageWith(
            $locale ? Translator::get($locale) : static::getTranslator(),
            'first_day_of_week',
        );
    }

    /**
     * Get the last day of week.
     *
     * @param string $locale local to consider the last day of week.
     *
     * @return int
     */
    public static function getWeekEndsAt(?string $locale = null): int
    {
        return static::weekRotate(static::getWeekStartsAt($locale), -1);
    }

    /**
     * Get weekend days
     */
    public static function getWeekendDays(): array
    {
        return FactoryImmutable::getInstance()->getWeekendDays();
    }

    /**
     * @deprecated To avoid conflict between different third-party libraries, static setters should not be used.
     *             You should rather consider week-end is always saturday and sunday, and if you have some custom
     *             week-end days to handle, give to those days an other name and create a macro for them:
     *
     *             ```
     *             Carbon::macro('isDayOff', function ($date) {
     *                 return $date->isSunday() || $date->isMonday();
     *             });
     *             Carbon::macro('isNotDayOff', function ($date) {
     *                 return !$date->isDayOff();
     *             });
     *             if ($someDate->isDayOff()) ...
     *             if ($someDate->isNotDayOff()) ...
     *             // Add 5 not-off days
     *             $count = 5;
     *             while ($someDate->isDayOff() || ($count-- > 0)) {
     *                 $someDate->addDay();
     *             }
     *             ```
     *
     * Set weekend days
     */
    public static function setWeekendDays(array $days): void
    {
        FactoryImmutable::getDefaultInstance()->setWeekendDays($days);
    }

    /**
     * Determine if a time string will produce a relative date.
     *
     * @return bool true if time match a relative date, false if absolute or invalid time string
     */
    public static function hasRelativeKeywords(?string $time): bool
    {
        if (!$time || strtotime($time) === false) {
            return false;
        }

        $date1 = new DateTime('2000-01-01T00:00:00Z');
        $date1->modify($time);
        $date2 = new DateTime('2001-12-25T00:00:00Z');
        $date2->modify($time);

        return $date1 != $date2;
    }

    ///////////////////////////////////////////////////////////////////
    /////////////////////// STRING FORMATTING /////////////////////////
    ///////////////////////////////////////////////////////////////////

    /**
     * Returns list of locale formats for ISO formatting.
     *
     * @param string|null $locale current locale used if null
     */
    public function getIsoFormats(?string $locale = null): array
    {
        return [
            'LT' => $this->getTranslationMessage('formats.LT', $locale),
            'LTS' => $this->getTranslationMessage('formats.LTS', $locale),
            'L' => $this->getTranslationMessage('formats.L', $locale),
            'LL' => $this->getTranslationMessage('formats.LL', $locale),
            'LLL' => $this->getTranslationMessage('formats.LLL', $locale),
            'LLLL' => $this->getTranslationMessage('formats.LLLL', $locale),
            'l' => $this->getTranslationMessage('formats.l', $locale),
            'll' => $this->getTranslationMessage('formats.ll', $locale),
            'lll' => $this->getTranslationMessage('formats.lll', $locale),
            'llll' => $this->getTranslationMessage('formats.llll', $locale),
        ];
    }

    /**
     * Returns list of calendar formats for ISO formatting.
     *
     * @param string|null $locale current locale used if null
     */
    public function getCalendarFormats(?string $locale = null): array
    {
        return [
            'sameDay' => $this->getTranslationMessage('calendar.sameDay', $locale, '[Today at] LT'),
            'nextDay' => $this->getTranslationMessage('calendar.nextDay', $locale, '[Tomorrow at] LT'),
            'nextWeek' => $this->getTranslationMessage('calendar.nextWeek', $locale, 'dddd [at] LT'),
            'lastDay' => $this->getTranslationMessage('calendar.lastDay', $locale, '[Yesterday at] LT'),
            'lastWeek' => $this->getTranslationMessage('calendar.lastWeek', $locale, '[Last] dddd [at] LT'),
            'sameElse' => $this->getTranslationMessage('calendar.sameElse', $locale, 'L'),
        ];
    }

    /**
     * Returns list of locale units for ISO formatting.
     */
    public static function getIsoUnits(): array
    {
        static $units = null;

        $units ??= [
            'OD' => ['getAltNumber', ['day']],
            'OM' => ['getAltNumber', ['month']],
            'OY' => ['getAltNumber', ['year']],
            'OH' => ['getAltNumber', ['hour']],
            'Oh' => ['getAltNumber', ['h']],
            'Om' => ['getAltNumber', ['minute']],
            'Os' => ['getAltNumber', ['second']],
            'D' => 'day',
            'DD' => ['rawFormat', ['d']],
            'Do' => ['ordinal', ['day', 'D']],
            'd' => 'dayOfWeek',
            'dd' => static fn (CarbonInterface $date, $originalFormat = null) => $date->getTranslatedMinDayName(
                $originalFormat,
            ),
            'ddd' => static fn (CarbonInterface $date, $originalFormat = null) => $date->getTranslatedShortDayName(
                $originalFormat,
            ),
            'dddd' => static fn (CarbonInterface $date, $originalFormat = null) => $date->getTranslatedDayName(
                $originalFormat,
            ),
            'DDD' => 'dayOfYear',
            'DDDD' => ['getPaddedUnit', ['dayOfYear', 3]],
            'DDDo' => ['ordinal', ['dayOfYear', 'DDD']],
            'e' => ['weekday', []],
            'E' => 'dayOfWeekIso',
            'H' => ['rawFormat', ['G']],
            'HH' => ['rawFormat', ['H']],
            'h' => ['rawFormat', ['g']],
            'hh' => ['rawFormat', ['h']],
            'k' => 'noZeroHour',
            'kk' => ['getPaddedUnit', ['noZeroHour']],
            'hmm' => ['rawFormat', ['gi']],
            'hmmss' => ['rawFormat', ['gis']],
            'Hmm' => ['rawFormat', ['Gi']],
            'Hmmss' => ['rawFormat', ['Gis']],
            'm' => 'minute',
            'mm' => ['rawFormat', ['i']],
            'a' => 'meridiem',
            'A' => 'upperMeridiem',
            's' => 'second',
            'ss' => ['getPaddedUnit', ['second']],
            'S' => static fn (CarbonInterface $date) => (string) floor($date->micro / 100000),
            'SS' => static fn (CarbonInterface $date) => self::floorZeroPad($date->micro / 10000, 2),
            'SSS' => static fn (CarbonInterface $date) => self::floorZeroPad($date->micro / 1000, 3),
            'SSSS' => static fn (CarbonInterface $date) => self::floorZeroPad($date->micro / 100, 4),
            'SSSSS' => static fn (CarbonInterface $date) => self::floorZeroPad($date->micro / 10, 5),
            'SSSSSS' => ['getPaddedUnit', ['micro', 6]],
            'SSSSSSS' => static fn (CarbonInterface $date) => self::floorZeroPad($date->micro * 10, 7),
            'SSSSSSSS' => static fn (CarbonInterface $date) => self::floorZeroPad($date->micro * 100, 8),
            'SSSSSSSSS' => static fn (CarbonInterface $date) => self::floorZeroPad($date->micro * 1000, 9),
            'M' => 'month',
            'MM' => ['rawFormat', ['m']],
            'MMM' => static function (CarbonInterface $date, $originalFormat = null) {
                $month = $date->getTranslatedShortMonthName($originalFormat);
                $suffix = $date->getTranslationMessage('mmm_suffix');
                if ($suffix && $month !== $date->monthName) {
                    $month .= $suffix;
                }

                return $month;
            },
            'MMMM' => static fn (CarbonInterface $date, $originalFormat = null) => $date->getTranslatedMonthName(
                $originalFormat,
            ),
            'Mo' => ['ordinal', ['month', 'M']],
            'Q' => 'quarter',
            'Qo' => ['ordinal', ['quarter', 'M']],
            'G' => 'isoWeekYear',
            'GG' => ['getPaddedUnit', ['isoWeekYear']],
            'GGG' => ['getPaddedUnit', ['isoWeekYear', 3]],
            'GGGG' => ['getPaddedUnit', ['isoWeekYear', 4]],
            'GGGGG' => ['getPaddedUnit', ['isoWeekYear', 5]],
            'g' => 'weekYear',
            'gg' => ['getPaddedUnit', ['weekYear']],
            'ggg' => ['getPaddedUnit', ['weekYear', 3]],
            'gggg' => ['getPaddedUnit', ['weekYear', 4]],
            'ggggg' => ['getPaddedUnit', ['weekYear', 5]],
            'W' => 'isoWeek',
            'WW' => ['getPaddedUnit', ['isoWeek']],
            'Wo' => ['ordinal', ['isoWeek', 'W']],
            'w' => 'week',
            'ww' => ['getPaddedUnit', ['week']],
            'wo' => ['ordinal', ['week', 'w']],
            'x' => ['valueOf', []],
            'X' => 'timestamp',
            'Y' => 'year',
            'YY' => ['rawFormat', ['y']],
            'YYYY' => ['getPaddedUnit', ['year', 4]],
            'YYYYY' => ['getPaddedUnit', ['year', 5]],
            'YYYYYY' => static fn (CarbonInterface $date) => ($date->year < 0 ? '' : '+').
                $date->getPaddedUnit('year', 6),
            'z' => ['rawFormat', ['T']],
            'zz' => 'tzName',
            'Z' => ['getOffsetString', []],
            'ZZ' => ['getOffsetString', ['']],
        ];

        return $units;
    }

    /**
     * Returns a unit of the instance padded with 0 by default or any other string if specified.
     *
     * @param string $unit      Carbon unit name
     * @param int    $length    Length of the output (2 by default)
     * @param string $padString String to use for padding ("0" by default)
     * @param int    $padType   Side(s) to pad (STR_PAD_LEFT by default)
     */
    public function getPaddedUnit($unit, $length = 2, $padString = '0', $padType = STR_PAD_LEFT): string
    {
        return ($this->$unit < 0 ? '-' : '').str_pad((string) abs($this->$unit), $length, $padString, $padType);
    }

    /**
     * Return a property with its ordinal.
     */
    public function ordinal(string $key, ?string $period = null): string
    {
        $number = $this->$key;
        $result = $this->translate('ordinal', [
            ':number' => $number,
            ':period' => (string) $period,
        ]);

        return (string) ($result === 'ordinal' ? $number : $result);
    }

    /**
     * Return the meridiem of the current time in the current locale.
     *
     * @param bool $isLower if true, returns lowercase variant if available in the current locale.
     */
    public function meridiem(bool $isLower = false): string
    {
        $hour = $this->hour;
        $index = $hour < static::HOURS_PER_DAY / 2 ? 0 : 1;

        if ($isLower) {
            $key = 'meridiem.'.($index + 2);
            $result = $this->translate($key);

            if ($result !== $key) {
                return $result;
            }
        }

        $key = "meridiem.$index";
        $result = $this->translate($key);
        if ($result === $key) {
            $result = $this->translate('meridiem', [
                ':hour' => $this->hour,
                ':minute' => $this->minute,
                ':isLower' => $isLower,
            ]);

            if ($result === 'meridiem') {
                return $isLower ? $this->latinMeridiem : $this->latinUpperMeridiem;
            }
        } elseif ($isLower) {
            $result = mb_strtolower($result);
        }

        return $result;
    }

    /**
     * Returns the alternative number for a given date property if available in the current locale.
     *
     * @param string $key date property
     */
    public function getAltNumber(string $key): string
    {
        return $this->translateNumber((int) (\strlen($key) > 1 ? $this->$key : $this->rawFormat($key)));
    }

    /**
     * Format in the current language using ISO replacement patterns.
     *
     * @param string|null $originalFormat provide context if a chunk has been passed alone
     */
    public function isoFormat(string $format, ?string $originalFormat = null): string
    {
        $result = '';
        $length = mb_strlen($format);
        $originalFormat ??= $format;
        $inEscaped = false;
        $formats = null;
        $units = null;

        for ($i = 0; $i < $length; $i++) {
            $char = mb_substr($format, $i, 1);

            if ($char === '\\') {
                $result .= mb_substr($format, ++$i, 1);

                continue;
            }

            if ($char === '[' && !$inEscaped) {
                $inEscaped = true;

                continue;
            }

            if ($char === ']' && $inEscaped) {
                $inEscaped = false;

                continue;
            }

            if ($inEscaped) {
                $result .= $char;

                continue;
            }

            $input = mb_substr($format, $i);

            if (preg_match('/^(LTS|LT|l{1,4}|L{1,4})/', $input, $match)) {
                if ($formats === null) {
                    $formats = $this->getIsoFormats();
                }

                $code = $match[0];
                $sequence = $formats[$code] ?? preg_replace_callback(
                    '/MMMM|MM|DD|dddd/',
                    static fn ($code) => mb_substr($code[0], 1),
                    $formats[strtoupper($code)] ?? '',
                );
                $rest = mb_substr($format, $i + mb_strlen($code));
                $format = mb_substr($format, 0, $i).$sequence.$rest;
                $length = mb_strlen($format);
                $input = $sequence.$rest;
            }

            if (preg_match('/^'.CarbonInterface::ISO_FORMAT_REGEXP.'/', $input, $match)) {
                $code = $match[0];

                if ($units === null) {
                    $units = static::getIsoUnits();
                }

                $sequence = $units[$code] ?? '';

                if ($sequence instanceof Closure) {
                    $sequence = $sequence($this, $originalFormat);
                } elseif (\is_array($sequence)) {
                    try {
                        $sequence = $this->{$sequence[0]}(...$sequence[1]);
                    } catch (ReflectionException | InvalidArgumentException | BadMethodCallException) {
                        $sequence = '';
                    }
                } elseif (\is_string($sequence)) {
                    $sequence = $this->$sequence ?? $code;
                }

                $format = mb_substr($format, 0, $i).$sequence.mb_substr($format, $i + mb_strlen($code));
                $i += mb_strlen((string) $sequence) - 1;
                $length = mb_strlen($format);
                $char = $sequence;
            }

            $result .= $char;
        }

        return $result;
    }

    /**
     * List of replacements from date() format to isoFormat().
     */
    public static function getFormatsToIsoReplacements(): array
    {
        static $replacements = null;

        $replacements ??= [
            'd' => true,
            'D' => 'ddd',
            'j' => true,
            'l' => 'dddd',
            'N' => true,
            'S' => static fn ($date) => str_replace((string) $date->rawFormat('j'), '', $date->isoFormat('Do')),
            'w' => true,
            'z' => true,
            'W' => true,
            'F' => 'MMMM',
            'm' => true,
            'M' => 'MMM',
            'n' => true,
            't' => true,
            'L' => true,
            'o' => true,
            'Y' => true,
            'y' => true,
            'a' => 'a',
            'A' => 'A',
            'B' => true,
            'g' => true,
            'G' => true,
            'h' => true,
            'H' => true,
            'i' => true,
            's' => true,
            'u' => true,
            'v' => true,
            'E' => true,
            'I' => true,
            'O' => true,
            'P' => true,
            'Z' => true,
            'c' => true,
            'r' => true,
            'U' => true,
            'T' => true,
        ];

        return $replacements;
    }

    /**
     * Format as ->format() do (using date replacements patterns from https://php.net/manual/en/function.date.php)
     * but translate words whenever possible (months, day names, etc.) using the current locale.
     */
    public function translatedFormat(string $format): string
    {
        $replacements = static::getFormatsToIsoReplacements();
        $context = '';
        $isoFormat = '';
        $length = mb_strlen($format);

        for ($i = 0; $i < $length; $i++) {
            $char = mb_substr($format, $i, 1);

            if ($char === '\\') {
                $replacement = mb_substr($format, $i, 2);
                $isoFormat .= $replacement;
                $i++;

                continue;
            }

            if (!isset($replacements[$char])) {
                $replacement = preg_match('/^[A-Za-z]$/', $char) ? "\\$char" : $char;
                $isoFormat .= $replacement;
                $context .= $replacement;

                continue;
            }

            $replacement = $replacements[$char];

            if ($replacement === true) {
                static $contextReplacements = null;

                if ($contextReplacements === null) {
                    $contextReplacements = [
                        'm' => 'MM',
                        'd' => 'DD',
                        't' => 'D',
                        'j' => 'D',
                        'N' => 'e',
                        'w' => 'e',
                        'n' => 'M',
                        'o' => 'YYYY',
                        'Y' => 'YYYY',
                        'y' => 'YY',
                        'g' => 'h',
                        'G' => 'H',
                        'h' => 'hh',
                        'H' => 'HH',
                        'i' => 'mm',
                        's' => 'ss',
                    ];
                }

                $isoFormat .= '['.$this->rawFormat($char).']';
                $context .= $contextReplacements[$char] ?? ' ';

                continue;
            }

            if ($replacement instanceof Closure) {
                $replacement = '['.$replacement($this).']';
                $isoFormat .= $replacement;
                $context .= $replacement;

                continue;
            }

            $isoFormat .= $replacement;
            $context .= $replacement;
        }

        return $this->isoFormat($isoFormat, $context);
    }

    /**
     * Returns the offset hour and minute formatted with +/- and a given separator (":" by default).
     * For example, if the time zone is 9 hours 30 minutes, you'll get "+09:30", with "@@" as first
     * argument, "+09@@30", with "" as first argument, "+0930". Negative offset will return something
     * like "-12:00".
     *
     * @param string $separator string to place between hours and minutes (":" by default)
     */
    public function getOffsetString(string $separator = ':'): string
    {
        $second = $this->getOffset();
        $symbol = $second < 0 ? '-' : '+';
        $minute = abs($second) / static::SECONDS_PER_MINUTE;
        $hour = self::floorZeroPad($minute / static::MINUTES_PER_HOUR, 2);
        $minute = self::floorZeroPad(((int) $minute) % static::MINUTES_PER_HOUR, 2);

        return "$symbol$hour$separator$minute";
    }

    /**
     * Dynamically handle calls to the class.
     *
     * @param string $method     magic method name called
     * @param array  $parameters parameters list
     *
     * @throws BadMethodCallException
     */
    public static function __callStatic(string $method, array $parameters): mixed
    {
        if (!static::hasMacro($method)) {
            foreach (static::getGenericMacros() as $callback) {
                try {
                    return static::executeStaticCallable($callback, $method, ...$parameters);
                } catch (BadMethodCallException) {
                    continue;
                }
            }

            if (static::isStrictModeEnabled()) {
                throw new UnknownMethodException(\sprintf('%s::%s', static::class, $method));
            }

            return null;
        }

        return static::executeStaticCallable(static::getMacro($method), ...$parameters);
    }

    /**
     * Set specified unit to new given value.
     *
     * @param string    $unit  year, month, day, hour, minute, second or microsecond
     * @param Month|int $value new value for given unit
     */
    public function setUnit(string $unit, Month|int|float|null $value = null): static
    {
        if (\is_float($value)) {
            $int = (int) $value;

            if ((float) $int !== $value) {
                throw new InvalidArgumentException(
                    "$unit cannot be changed to float value $value, integer expected",
                );
            }

            $value = $int;
        }

        $unit = static::singularUnit($unit);
        $value = self::monthToInt($value, $unit);
        $dateUnits = ['year', 'month', 'day'];

        if (\in_array($unit, $dateUnits)) {
            return $this->setDate(...array_map(
                fn ($name) => (int) ($name === $unit ? $value : $this->$name),
                $dateUnits,
            ));
        }

        $units = ['hour', 'minute', 'second', 'micro'];

        if ($unit === 'millisecond' || $unit === 'milli') {
            $value *= 1000;
            $unit = 'micro';
        } elseif ($unit === 'microsecond') {
            $unit = 'micro';
        }

        return $this->setTime(...array_map(
            fn ($name) => (int) ($name === $unit ? $value : $this->$name),
            $units,
        ));
    }

    /**
     * Returns standardized singular of a given singular/plural unit name (in English).
     */
    public static function singularUnit(string $unit): string
    {
        $unit = rtrim(mb_strtolower($unit), 's');

        return match ($unit) {
            'centurie' => 'century',
            'millennia' => 'millennium',
            default => $unit,
        };
    }

    /**
     * Returns standardized plural of a given singular/plural unit name (in English).
     */
    public static function pluralUnit(string $unit): string
    {
        $unit = rtrim(strtolower($unit), 's');

        return match ($unit) {
            'century' => 'centuries',
            'millennium', 'millennia' => 'millennia',
            default => "{$unit}s",
        };
    }

    public static function sleep(int|float $seconds): void
    {
        if (static::hasTestNow()) {
            static::setTestNow(static::getTestNow()->avoidMutation()->addSeconds($seconds));

            return;
        }

        (new NativeClock('UTC'))->sleep($seconds);
    }

    /**
     * Dynamically handle calls to the class.
     *
     * @param string $method     magic method name called
     * @param array  $parameters parameters list
     *
     * @throws UnknownMethodException|BadMethodCallException|ReflectionException|Throwable
     */
    public function __call(string $method, array $parameters): mixed
    {
        $unit = rtrim($method, 's');

        return $this->callDiffAlias($unit, $parameters)
            ?? $this->callHumanDiffAlias($unit, $parameters)
            ?? $this->callRoundMethod($unit, $parameters)
            ?? $this->callIsMethod($unit, $parameters)
            ?? $this->callModifierMethod($unit, $parameters)
            ?? $this->callPeriodMethod($method, $parameters)
            ?? $this->callGetOrSetMethod($method, $parameters)
            ?? $this->callMacroMethod($method, $parameters);
    }

    /**
     * Return the Carbon instance passed through, a now instance in the same timezone
     * if null given or parse the input if string given.
     */
    protected function resolveCarbon(DateTimeInterface|string|null $date): self
    {
        if (!$date) {
            return $this->nowWithSameTz();
        }

        if (\is_string($date)) {
            return $this->transmitFactory(fn () => static::parse($date, $this->getTimezone()));
        }

        return $date instanceof self ? $date : $this->transmitFactory(static fn () => static::instance($date));
    }

    protected static function weekRotate(int $day, int $rotation): int
    {
        return (static::DAYS_PER_WEEK + $rotation % static::DAYS_PER_WEEK + $day) % static::DAYS_PER_WEEK;
    }

    protected function executeCallable(callable $macro, ...$parameters)
    {
        if ($macro instanceof Closure) {
            $boundMacro = @$macro->bindTo($this, static::class) ?: @$macro->bindTo(null, static::class);

            return \call_user_func_array($boundMacro ?: $macro, $parameters);
        }

        return \call_user_func_array($macro, $parameters);
    }

    protected function executeCallableWithContext(callable $macro, ...$parameters)
    {
        return static::bindMacroContext($this, function () use (&$macro, &$parameters) {
            return $this->executeCallable($macro, ...$parameters);
        });
    }

    protected function getAllGenericMacros(): Generator
    {
        yield from $this->localGenericMacros ?? [];
        yield from $this->transmitFactory(static fn () => static::getGenericMacros());
    }

    protected static function getGenericMacros(): Generator
    {
        foreach ((FactoryImmutable::getInstance()->getSettings()['genericMacros'] ?? []) as $list) {
            foreach ($list as $macro) {
                yield $macro;
            }
        }
    }

    protected static function executeStaticCallable(callable $macro, ...$parameters)
    {
        return static::bindMacroContext(null, function () use (&$macro, &$parameters) {
            if ($macro instanceof Closure) {
                $boundMacro = @Closure::bind($macro, null, static::class);

                return \call_user_func_array($boundMacro ?: $macro, $parameters);
            }

            return \call_user_func_array($macro, $parameters);
        });
    }

    protected function getTranslatedFormByRegExp($baseKey, $keySuffix, $context, $subKey, $defaultValue)
    {
        $key = $baseKey.$keySuffix;
        $standaloneKey = "{$key}_standalone";
        $baseTranslation = $this->getTranslationMessage($key);

        if ($baseTranslation instanceof Closure) {
            return $baseTranslation($this, $context, $subKey) ?: $defaultValue;
        }

        if (
            $this->getTranslationMessage("$standaloneKey.$subKey") &&
            (!$context || (($regExp = $this->getTranslationMessage("{$baseKey}_regexp")) && !preg_match($regExp, $context)))
        ) {
            $key = $standaloneKey;
        }

        return $this->getTranslationMessage("$key.$subKey", null, $defaultValue);
    }

    private function callGetOrSetMethod(string $method, array $parameters): mixed
    {
        if (preg_match('/^([a-z]{2,})(In|Of)([A-Z][a-z]+)$/', $method)) {
            $localStrictModeEnabled = $this->localStrictModeEnabled;
            $this->localStrictModeEnabled = true;

            try {
                return $this->callGetOrSet($method, $parameters[0] ?? null);
            } catch (UnknownGetterException|UnknownSetterException|ImmutableException) {
                // continue to macro
            } finally {
                $this->localStrictModeEnabled = $localStrictModeEnabled;
            }
        }

        return null;
    }

    private function callGetOrSet(string $name, mixed $value): mixed
    {
        if ($value !== null) {
            if (\is_string($value) || \is_int($value) || \is_float($value) || $value instanceof DateTimeZone || $value instanceof Month) {
                return $this->set($name, $value);
            }

            return null;
        }

        return $this->get($name);
    }

    private function getUTCUnit(string $unit): ?string
    {
        if (str_starts_with($unit, 'Real')) {
            return substr($unit, 4);
        }

        if (str_starts_with($unit, 'UTC')) {
            return substr($unit, 3);
        }

        return null;
    }

    private function callDiffAlias(string $method, array $parameters): mixed
    {
        if (preg_match('/^(diff|floatDiff)In(Real|UTC|Utc)?(.+)$/', $method, $match)) {
            $mode = strtoupper($match[2] ?? '');
            $betterMethod = $match[1] === 'floatDiff' ? str_replace('floatDiff', 'diff', $method) : null;

            if ($mode === 'REAL') {
                $mode = 'UTC';
                $betterMethod = str_replace($match[2], 'UTC', $betterMethod ?? $method);
            }

            if ($betterMethod) {
                @trigger_error(
                    "Use the method $betterMethod instead to make it more explicit about what it does.\n".
                    'On next major version, "float" prefix will be removed (as all diff are now returning floating numbers)'.
                    ' and "Real" methods will be removed in favor of "UTC" because what it actually does is to convert both'.
                    ' dates to UTC timezone before comparison, while by default it does it only if both dates don\'t have'.
                    ' exactly the same timezone (Note: 2 timezones with the same offset but different names are considered'.
                    " different as it's not safe to assume they will always have the same offset).",
                    \E_USER_DEPRECATED,
                );
            }

            $unit = self::pluralUnit($match[3]);
            $diffMethod = 'diffIn'.ucfirst($unit);

            if (\in_array($unit, ['days', 'weeks', 'months', 'quarters', 'years'])) {
                $parameters['utc'] = ($mode === 'UTC');
            }

            if (method_exists($this, $diffMethod)) {
                return $this->$diffMethod(...$parameters);
            }
        }

        return null;
    }

    private function callHumanDiffAlias(string $method, array $parameters): ?string
    {
        $diffSizes = [
            // @mode diffForHumans
            'short' => true,
            // @mode diffForHumans
            'long' => false,
        ];
        $diffSyntaxModes = [
            // @call diffForHumans
            'Absolute' => CarbonInterface::DIFF_ABSOLUTE,
            // @call diffForHumans
            'Relative' => CarbonInterface::DIFF_RELATIVE_AUTO,
            // @call diffForHumans
            'RelativeToNow' => CarbonInterface::DIFF_RELATIVE_TO_NOW,
            // @call diffForHumans
            'RelativeToOther' => CarbonInterface::DIFF_RELATIVE_TO_OTHER,
        ];
        $sizePattern = implode('|', array_keys($diffSizes));
        $syntaxPattern = implode('|', array_keys($diffSyntaxModes));

        if (preg_match("/^(?<size>$sizePattern)(?<syntax>$syntaxPattern)DiffForHuman$/", $method, $match)) {
            $dates = array_filter($parameters, function ($parameter) {
                return $parameter instanceof DateTimeInterface;
            });
            $other = null;

            if (\count($dates)) {
                $key = key($dates);
                $other = current($dates);
                array_splice($parameters, $key, 1);
            }

            return $this->diffForHumans($other, $diffSyntaxModes[$match['syntax']], $diffSizes[$match['size']], ...$parameters);
        }

        return null;
    }

    private function callIsMethod(string $unit, array $parameters): ?bool
    {
        if (!str_starts_with($unit, 'is')) {
            return null;
        }

        $word = substr($unit, 2);

        if (\in_array($word, static::$days, true)) {
            return $this->isDayOfWeek($word);
        }

        return match ($word) {
            // @call is Check if the current instance has UTC timezone. (Both isUtc and isUTC cases are valid.)
            'Utc', 'UTC' => $this->utc,
            // @call is Check if the current instance has non-UTC timezone.
            'Local' => $this->local,
            // @call is Check if the current instance is a valid date.
            'Valid' => $this->year !== 0,
            // @call is Check if the current instance is in a daylight saving time.
            'DST' => $this->dst,
            default => $this->callComparatorMethod($word, $parameters),
        };
    }

    private function callComparatorMethod(string $unit, array $parameters): ?bool
    {
        $start = substr($unit, 0, 4);
        $factor = -1;

        if ($start === 'Last') {
            $start = 'Next';
            $factor = 1;
        }

        if ($start === 'Next') {
            $lowerUnit = strtolower(substr($unit, 4));

            if (static::isModifiableUnit($lowerUnit)) {
                return $this->avoidMutation()->addUnit($lowerUnit, $factor, false)->isSameUnit($lowerUnit, ...($parameters ?: ['now']));
            }
        }

        if ($start === 'Same') {
            try {
                return $this->isSameUnit(strtolower(substr($unit, 4)), ...$parameters);
            } catch (BadComparisonUnitException) {
                // Try next
            }
        }

        if (str_starts_with($unit, 'Current')) {
            try {
                return $this->isCurrentUnit(strtolower(substr($unit, 7)));
            } catch (BadComparisonUnitException | BadMethodCallException) {
                // Try next
            }
        }

        return null;
    }

    private function callModifierMethod(string $unit, array $parameters): ?static
    {
        $action = substr($unit, 0, 3);
        $overflow = null;

        if ($action === 'set') {
            $unit = strtolower(substr($unit, 3));
        }

        if (\in_array($unit, static::$units, true)) {
            return $this->setUnit($unit, ...$parameters);
        }

        if ($action === 'add' || $action === 'sub') {
            $unit = substr($unit, 3);
            $utcUnit = $this->getUTCUnit($unit);

            if ($utcUnit) {
                $unit = static::singularUnit($utcUnit);

                return $this->{"{$action}UTCUnit"}($unit, ...$parameters);
            }

            if (preg_match('/^(Month|Quarter|Year|Decade|Century|Centurie|Millennium|Millennia)s?(No|With|Without|WithNo)Overflow$/', $unit, $match)) {
                $unit = $match[1];
                $overflow = $match[2] === 'With';
            }

            $unit = static::singularUnit($unit);
        }

        if (static::isModifiableUnit($unit)) {
            return $this->{"{$action}Unit"}($unit, $this->getMagicParameter($parameters, 0, 'value', 1), $overflow);
        }

        return null;
    }

    private function callPeriodMethod(string $method, array $parameters): ?CarbonPeriod
    {
        if (str_ends_with($method, 'Until')) {
            try {
                $unit = static::singularUnit(substr($method, 0, -5));

                return $this->range(
                    $this->getMagicParameter($parameters, 0, 'endDate', $this),
                    $this->getMagicParameter($parameters, 1, 'factor', 1),
                    $unit
                );
            } catch (InvalidArgumentException) {
                // Try macros
            }
        }

        return null;
    }

    private function callMacroMethod(string $method, array $parameters): mixed
    {
        return static::bindMacroContext($this, function () use (&$method, &$parameters) {
            $macro = $this->getLocalMacro($method);

            if (!$macro) {
                foreach ($this->getAllGenericMacros() as $callback) {
                    try {
                        return $this->executeCallable($callback, $method, ...$parameters);
                    } catch (BadMethodCallException) {
                        continue;
                    }
                }

                if ($this->isLocalStrictModeEnabled()) {
                    throw new UnknownMethodException($method);
                }

                return null;
            }

            return $this->executeCallable($macro, ...$parameters);
        });
    }

    private static function floorZeroPad(int|float $value, int $length): string
    {
        return str_pad((string) floor($value), $length, '0', STR_PAD_LEFT);
    }

    /**
     * @template T of CarbonInterface
     *
     * @param T $date
     *
     * @return T
     */
    private function mutateIfMutable(CarbonInterface $date): CarbonInterface
    {
        return $this instanceof DateTimeImmutable
            ? $date
            : $this->modify('@'.$date->rawFormat('U.u'))->setTimezone($date->getTimezone());
    }
}
