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 $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 $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 $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 $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 $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 $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 $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 $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 $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 $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 $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 $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 $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 $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 $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 $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 $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 $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 $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 $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 $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 $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 $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 $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 $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 $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 $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 $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 $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 addRealMicros(int $value = 1) Add microseconds (the $value count passed in) to the instance (using timestamp). * @method CarbonInterface addRealMicro() Add one microsecond to the instance (using timestamp). * @method CarbonInterface subRealMicros(int $value = 1) Sub microseconds (the $value count passed in) to the instance (using timestamp). * @method CarbonInterface subRealMicro() Sub one microsecond to the instance (using timestamp). * @method CarbonPeriod microsUntil($endDate = null, int $factor = 1) Return an iterable period from current date to given end (string, DateTime or Carbon instance) for each microsecond or every X microseconds if a factor is given. * @method CarbonInterface addRealMicroseconds(int $value = 1) Add microseconds (the $value count passed in) to the instance (using timestamp). * @method CarbonInterface addRealMicrosecond() Add one microsecond to the instance (using timestamp). * @method CarbonInterface subRealMicroseconds(int $value = 1) Sub microseconds (the $value count passed in) to the instance (using timestamp). * @method CarbonInterface subRealMicrosecond() Sub one microsecond to the instance (using timestamp). * @method CarbonPeriod microsecondsUntil($endDate = null, int $factor = 1) Return an iterable period from current date to given end (string, DateTime or Carbon instance) for each microsecond or every X microseconds if a factor is given. * @method CarbonInterface addRealMillis(int $value = 1) Add milliseconds (the $value count passed in) to the instance (using timestamp). * @method CarbonInterface addRealMilli() Add one millisecond to the instance (using timestamp). * @method CarbonInterface subRealMillis(int $value = 1) Sub milliseconds (the $value count passed in) to the instance (using timestamp). * @method CarbonInterface subRealMilli() Sub one millisecond to the instance (using timestamp). * @method CarbonPeriod millisUntil($endDate = null, int $factor = 1) Return an iterable period from current date to given end (string, DateTime or Carbon instance) for each millisecond or every X milliseconds if a factor is given. * @method CarbonInterface addRealMilliseconds(int $value = 1) Add milliseconds (the $value count passed in) to the instance (using timestamp). * @method CarbonInterface addRealMillisecond() Add one millisecond to the instance (using timestamp). * @method CarbonInterface subRealMilliseconds(int $value = 1) Sub milliseconds (the $value count passed in) to the instance (using timestamp). * @method CarbonInterface subRealMillisecond() Sub one millisecond to the instance (using timestamp). * @method CarbonPeriod millisecondsUntil($endDate = null, int $factor = 1) Return an iterable period from current date to given end (string, DateTime or Carbon instance) for each millisecond or every X milliseconds if a factor is given. * @method CarbonInterface addRealSeconds(int $value = 1) Add seconds (the $value count passed in) to the instance (using timestamp). * @method CarbonInterface addRealSecond() Add one second to the instance (using timestamp). * @method CarbonInterface subRealSeconds(int $value = 1) Sub seconds (the $value count passed in) to the instance (using timestamp). * @method CarbonInterface subRealSecond() Sub one second to the instance (using timestamp). * @method CarbonPeriod secondsUntil($endDate = null, int $factor = 1) Return an iterable period from current date to given end (string, DateTime or Carbon instance) for each second or every X seconds if a factor is given. * @method CarbonInterface addRealMinutes(int $value = 1) Add minutes (the $value count passed in) to the instance (using timestamp). * @method CarbonInterface addRealMinute() Add one minute to the instance (using timestamp). * @method CarbonInterface subRealMinutes(int $value = 1) Sub minutes (the $value count passed in) to the instance (using timestamp). * @method CarbonInterface subRealMinute() Sub one minute to the instance (using timestamp). * @method CarbonPeriod minutesUntil($endDate = null, int $factor = 1) Return an iterable period from current date to given end (string, DateTime or Carbon instance) for each minute or every X minutes if a factor is given. * @method CarbonInterface addRealHours(int $value = 1) Add hours (the $value count passed in) to the instance (using timestamp). * @method CarbonInterface addRealHour() Add one hour to the instance (using timestamp). * @method CarbonInterface subRealHours(int $value = 1) Sub hours (the $value count passed in) to the instance (using timestamp). * @method CarbonInterface subRealHour() Sub one hour to the instance (using timestamp). * @method CarbonPeriod hoursUntil($endDate = null, int $factor = 1) Return an iterable period from current date to given end (string, DateTime or Carbon instance) for each hour or every X hours if a factor is given. * @method CarbonInterface addRealDays(int $value = 1) Add days (the $value count passed in) to the instance (using timestamp). * @method CarbonInterface addRealDay() Add one day to the instance (using timestamp). * @method CarbonInterface subRealDays(int $value = 1) Sub days (the $value count passed in) to the instance (using timestamp). * @method CarbonInterface subRealDay() Sub one day to the instance (using timestamp). * @method CarbonPeriod daysUntil($endDate = null, int $factor = 1) Return an iterable period from current date to given end (string, DateTime or Carbon instance) for each day or every X days if a factor is given. * @method CarbonInterface addRealWeeks(int $value = 1) Add weeks (the $value count passed in) to the instance (using timestamp). * @method CarbonInterface addRealWeek() Add one week to the instance (using timestamp). * @method CarbonInterface subRealWeeks(int $value = 1) Sub weeks (the $value count passed in) to the instance (using timestamp). * @method CarbonInterface subRealWeek() Sub one week to the instance (using timestamp). * @method CarbonPeriod weeksUntil($endDate = null, int $factor = 1) Return an iterable period from current date to given end (string, DateTime or Carbon instance) for each week or every X weeks if a factor is given. * @method CarbonInterface addRealMonths(int $value = 1) Add months (the $value count passed in) to the instance (using timestamp). * @method CarbonInterface addRealMonth() Add one month to the instance (using timestamp). * @method CarbonInterface subRealMonths(int $value = 1) Sub months (the $value count passed in) to the instance (using timestamp). * @method CarbonInterface subRealMonth() Sub one month to the instance (using timestamp). * @method CarbonPeriod monthsUntil($endDate = null, int $factor = 1) Return an iterable period from current date to given end (string, DateTime or Carbon instance) for each month or every X months if a factor is given. * @method CarbonInterface addRealQuarters(int $value = 1) Add quarters (the $value count passed in) to the instance (using timestamp). * @method CarbonInterface addRealQuarter() Add one quarter to the instance (using timestamp). * @method CarbonInterface subRealQuarters(int $value = 1) Sub quarters (the $value count passed in) to the instance (using timestamp). * @method CarbonInterface subRealQuarter() Sub one quarter to the instance (using timestamp). * @method CarbonPeriod quartersUntil($endDate = null, int $factor = 1) Return an iterable period from current date to given end (string, DateTime or Carbon instance) for each quarter or every X quarters if a factor is given. * @method CarbonInterface addRealYears(int $value = 1) Add years (the $value count passed in) to the instance (using timestamp). * @method CarbonInterface addRealYear() Add one year to the instance (using timestamp). * @method CarbonInterface subRealYears(int $value = 1) Sub years (the $value count passed in) to the instance (using timestamp). * @method CarbonInterface subRealYear() Sub one year to the instance (using timestamp). * @method CarbonPeriod yearsUntil($endDate = null, int $factor = 1) Return an iterable period from current date to given end (string, DateTime or Carbon instance) for each year or every X years if a factor is given. * @method CarbonInterface addRealDecades(int $value = 1) Add decades (the $value count passed in) to the instance (using timestamp). * @method CarbonInterface addRealDecade() Add one decade to the instance (using timestamp). * @method CarbonInterface subRealDecades(int $value = 1) Sub decades (the $value count passed in) to the instance (using timestamp). * @method CarbonInterface subRealDecade() Sub one decade to the instance (using timestamp). * @method CarbonPeriod decadesUntil($endDate = null, int $factor = 1) Return an iterable period from current date to given end (string, DateTime or Carbon instance) for each decade or every X decades if a factor is given. * @method CarbonInterface addRealCenturies(int $value = 1) Add centuries (the $value count passed in) to the instance (using timestamp). * @method CarbonInterface addRealCentury() Add one century to the instance (using timestamp). * @method CarbonInterface subRealCenturies(int $value = 1) Sub centuries (the $value count passed in) to the instance (using timestamp). * @method CarbonInterface subRealCentury() Sub one century to the instance (using timestamp). * @method CarbonPeriod centuriesUntil($endDate = null, int $factor = 1) Return an iterable period from current date to given end (string, DateTime or Carbon instance) for each century or every X centuries if a factor is given. * @method CarbonInterface addRealMillennia(int $value = 1) Add millennia (the $value count passed in) to the instance (using timestamp). * @method CarbonInterface addRealMillennium() Add one millennium to the instance (using timestamp). * @method CarbonInterface subRealMillennia(int $value = 1) Sub millennia (the $value count passed in) to the instance (using timestamp). * @method CarbonInterface subRealMillennium() Sub one millennium to the instance (using timestamp). * @method CarbonPeriod millenniaUntil($endDate = null, int $factor = 1) Return an iterable period from current date to given end (string, DateTime or Carbon instance) for each millennium or every X millennia if a factor is given. * @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.) * * */ 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', ]; /** * Will UTF8 encoding be used to print localized date/time ? * * @var bool */ protected static $utf8 = false; /** * 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|null $object original value to get CarbonTimeZone from it. * @param DateTimeZone|string|int|null $objectDump dump of the object for error messages. * * @throws InvalidTimeZoneException * * @return CarbonTimeZone|false */ protected static function safeCreateDateTimeZone($object, $objectDump = null) { return CarbonTimeZone::instance($object, $objectDump); } /** * Get the TimeZone associated with the Carbon instance (as CarbonTimeZone). * * @return CarbonTimeZone * * @link https://php.net/manual/en/datetime.gettimezone.php */ #[ReturnTypeWillChange] public function getTimezone() { return CarbonTimeZone::instance(parent::getTimezone()); } /** * List of minimum and maximums for each unit. * * @param int $daysInMonth * * @return array */ 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(): self { if ($this instanceof DateTimeImmutable) { return $this; } return clone $this; } /** * Returns a present instance in the same timezone. * * @return static */ public function nowWithSameTz() { return static::now($this->getTimezone()); } /** * Throws an exception if the given object is not a DateTime and does not implement DateTimeInterface. * * @param mixed $date * @param string|array $other * * @throws InvalidTypeException */ protected static function expectDateTime($date, $other = []) { $message = 'Expected '; foreach ((array) $other as $expect) { $message .= "$expect, "; } if (!$date instanceof DateTime && !$date instanceof DateTimeInterface) { throw new InvalidTypeException( $message.'DateTime or DateTimeInterface, '. (\is_object($date) ? \get_class($date) : \gettype($date)).' given' ); } } /** * 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|DateTimeInterface|string|null $date * * @return static */ protected function resolveCarbon($date = null) { if (!$date) { return $this->nowWithSameTz(); } if (\is_string($date)) { return static::parse($date, $this->getTimezone()); } static::expectDateTime($date, ['null', 'string']); return $date instanceof self ? $date : static::instance($date); } /** * Return the Carbon instance passed through, a now instance in UTC * if null given or parse the input if string given (using current timezone * then switching to UTC). * * @param Carbon|DateTimeInterface|string|null $date * * @return static */ protected function resolveUTC($date = null): self { if (!$date) { return static::now('UTC'); } if (\is_string($date)) { return static::parse($date, $this->getTimezone())->utc(); } static::expectDateTime($date, ['null', 'string']); return $date instanceof self ? $date : static::instance($date)->utc(); } /** * 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 * * @param string $name * * @throws UnknownGetterException * * @return string|int|bool|DateTimeZone|null */ public function __get($name) { return $this->get($name); } /** * Get a part of the Carbon object * * @param string $name * * @throws UnknownGetterException * * @return string|int|bool|DateTimeZone|null */ public function get($name) { static $formats = [ // @property int 'year' => 'Y', // @property int 'yearIso' => 'o', // @property int // @call isSameUnit '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-read int 0 (for Sunday) through 6 (for Saturday) 'dayOfWeek' => 'w', // @property-read int 1 (for Monday) through 7 (for Sunday) 'dayOfWeekIso' => 'N', // @property-read 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 string the day of week in current locale LC_TIME // @deprecated // reason: It uses OS language package and strftime() which is deprecated since PHP 8.1. // replacement: Use ->isoFormat('MMM') instead. // since: 2.55.0 'localeDayOfWeek' => '%A', // @property string the abbreviated day of week in current locale LC_TIME // @deprecated // reason: It uses OS language package and strftime() which is deprecated since PHP 8.1. // replacement: Use ->isoFormat('dddd') instead. // since: 2.55.0 'shortLocaleDayOfWeek' => '%a', // @property string the month in current locale LC_TIME // @deprecated // reason: It uses OS language package and strftime() which is deprecated since PHP 8.1. // replacement: Use ->isoFormat('ddd') instead. // since: 2.55.0 'localeMonth' => '%B', // @property string the abbreviated month in current locale LC_TIME // @deprecated // reason: It uses OS language package and strftime() which is deprecated since PHP 8.1. // replacement: Use ->isoFormat('MMMM') instead. // since: 2.55.0 'shortLocaleMonth' => '%b', // @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]): $format = $formats[$name]; $method = str_starts_with($format, '%') ? 'formatLocalized' : 'rawFormat'; $value = $this->$method($format); 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-read 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 $this->localTranslator ? ($this->getTranslationMessage('first_day_of_week') ?? 0) : static::getWeekStartsAt(); // @property-read int 0 through 6 case $name === 'lastWeekDay': return $this->localTranslator ? (($this->getTranslationMessage('first_day_of_week') ?? 0) + static::DAYS_PER_WEEK - 1) % static::DAYS_PER_WEEK : static::getWeekEndsAt(); // @property int 1 through 366 case $name === 'dayOfYear': return 1 + (int) ($this->rawFormat('z')); // @property-read int 365 or 366 case $name === 'daysInYear': return $this->isLeapYear() ? 366 : 365; // @property int does a diffInYears() with default parameters case $name === 'age': return $this->diffInYears(); // @property-read int the quarter of this instance, 1 - 4 // @call isSameUnit 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 CarbonTimeZone $timezone the current timezone // @property CarbonTimeZone $tz alias of $timezone case $name === 'timezone' || $name === 'tz': return CarbonTimeZone::instance($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(); 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 $e) { 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 * * @param string|array $name * @param string|int|DateTimeZone $value * * @throws ImmutableException|UnknownSetterException * * @return $this */ public function set($name, $value = null) { 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; } 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 = $value; $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 '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: $macro = $this->getLocalMacro('set'.ucfirst($name)); if ($macro) { $this->executeCallableWithContext($macro, $value); break; } if ($this->localStrictModeEnabled ?? static::isStrictModeEnabled()) { throw new UnknownSetterException($name); } $this->$name = $value; } return $this; } 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); } /** * 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 * * @return string */ public function getTranslatedDayName($context = null, $keySuffix = '', $defaultValue = null) { 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 * * @return string */ public function getTranslatedShortDayName($context = null) { 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 * * @return string */ public function getTranslatedMinDayName($context = null) { 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 * * @return string */ public function getTranslatedMonthName($context = null, $keySuffix = '', $defaultValue = null) { 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 * * @return string */ public function getTranslatedShortMonthName($context = null) { return $this->getTranslatedMonthName($context, '_short', $this->shortEnglishMonth); } /** * Get/set the day of year. * * @param int|null $value new value for day of year if using as setter. * * @return static|int */ public function dayOfYear($value = null) { $dayOfYear = $this->dayOfYear; return $value === null ? $dayOfYear : $this->addDays($value - $dayOfYear); } /** * Get/set the weekday from 0 (Sunday) to 6 (Saturday). * * @param int|null $value new value for weekday if using as setter. * * @return static|int */ public function weekday($value = null) { if ($value === null) { return $this->dayOfWeek; } $firstDay = (int) ($this->getTranslationMessage('first_day_of_week') ?? 0); $dayOfWeek = ($this->dayOfWeek + 7 - $firstDay) % 7; return $this->addDays((($value + 7 - $firstDay) % 7) - $dayOfWeek); } /** * Get/set the ISO weekday from 1 (Monday) to 7 (Sunday). * * @param int|null $value new value for weekday if using as setter. * * @return static|int */ public function isoWeekday($value = null) { $dayOfWeekIso = $this->dayOfWeekIso; return $value === null ? $dayOfWeekIso : $this->addDays($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 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.) * * @return int */ public function getDaysFromStartOfWeek(int $weekStartsAt = null): int { $firstDay = (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 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.) * * @return static */ public function setDaysFromStartOfWeek(int $numberOfDays, int $weekStartsAt = null) { return $this->addDays($numberOfDays - $this->getDaysFromStartOfWeek($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 * * @return static */ public function setUnitNoOverflow($valueUnit, $value, $overflowUnit) { try { $original = $this->avoidMutation(); /** @var static $date */ $date = $this->$valueUnit($value); $end = $original->avoidMutation()->endOf($overflowUnit); $start = $original->avoidMutation()->startOf($overflowUnit); if ($date < $start) { $date = $date->setDateTimeFrom($start); } elseif ($date > $end) { $date = $date->setDateTimeFrom($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 * * @return static */ public function addUnitNoOverflow($valueUnit, $value, $overflowUnit) { 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 * * @return static */ public function subUnitNoOverflow($valueUnit, $value, $overflowUnit) { 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. * * @param int|null $minuteOffset * * @return int|static */ public function utcOffset(int $minuteOffset = null) { if (\func_num_args() < 1) { 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 * * @param int $year * @param int $month * @param int $day * * @return static */ #[ReturnTypeWillChange] public function setDate($year, $month, $day) { return parent::setDate((int) $year, (int) $month, (int) $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 * * @param int $year * @param int $week * @param int $day * * @return static */ #[ReturnTypeWillChange] public function setISODate($year, $week, $day = 1) { return parent::setISODate((int) $year, (int) $week, (int) $day); } /** * Set the date and time all together. * * @param int $year * @param int $month * @param int $day * @param int $hour * @param int $minute * @param int $second * @param int $microseconds * * @return static */ public function setDateTime($year, $month, $day, $hour, $minute, $second = 0, $microseconds = 0) { return $this->setDate($year, $month, $day)->setTime((int) $hour, (int) $minute, (int) $second, (int) $microseconds); } /** * Resets the current time of the DateTime object to a different time. * * @see https://php.net/manual/en/datetime.settime.php * * @param int $hour * @param int $minute * @param int $second * @param int $microseconds * * @return static */ #[ReturnTypeWillChange] public function setTime($hour, $minute, $second = 0, $microseconds = 0) { return parent::setTime((int) $hour, (int) $minute, (int) $second, (int) $microseconds); } /** * Set the instance's timestamp. * * Timestamp input can be given as int, float or a string containing one or more numbers. * * @param float|int|string $unixTimestamp * * @return static */ #[ReturnTypeWillChange] public function setTimestamp($unixTimestamp) { [$timestamp, $microseconds] = self::getIntegerAndDecimalParts($unixTimestamp); return parent::setTimestamp((int) $timestamp)->setMicroseconds((int) $microseconds); } /** * Set the time by time string. * * @param string $time * * @return static */ public function setTimeFromTimeString($time) { if (!str_contains($time, ':')) { $time .= ':0'; } return $this->modify($time); } /** * @alias setTimezone * * @param DateTimeZone|string $value * * @return static */ public function timezone($value) { return $this->setTimezone($value); } /** * Set the timezone or returns the timezone name if no arguments passed. * * @param DateTimeZone|string $value * * @return static|string */ public function tz($value = null) { if (\func_num_args() < 1) { return $this->tzName; } return $this->setTimezone($value); } /** * Set the instance's timezone from a string or object. * * @param DateTimeZone|string $value * * @return static */ #[ReturnTypeWillChange] public function setTimezone($value) { $tz = static::safeCreateDateTimeZone($value); if ($tz === false && !self::isStrictModeEnabled()) { $tz = new CarbonTimeZone(); } return parent::setTimezone($tz); } /** * Set the instance's timezone from a string or object and add/subtract the offset difference. * * @param DateTimeZone|string $value * * @return static */ public function shiftTimezone($value) { $dateTimeString = $this->format('Y-m-d H:i:s.u'); return $this ->setTimezone($value) ->modify($dateTimeString); } /** * Set the instance's timezone to UTC. * * @return static */ public function utc() { return $this->setTimezone('UTC'); } /** * Set the year, month, and date for this instance to that of the passed instance. * * @param Carbon|DateTimeInterface $date now if null * * @return static */ public function setDateFrom($date = null) { $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. * * @param Carbon|DateTimeInterface $date now if null * * @return static */ public function setTimeFrom($date = null) { $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. * * @param Carbon|DateTimeInterface $date * * @return static */ public function setDateTimeFrom($date = null) { $date = $this->resolveCarbon($date); return $this->modify($date->rawFormat('Y-m-d H:i:s.u')); } /** * Get the days of the week * * @return array */ public static function getDays() { return static::$days; } /////////////////////////////////////////////////////////////////// /////////////////////// WEEK SPECIAL DAYS ///////////////////////// /////////////////////////////////////////////////////////////////// private static function getFirstDayOfWeek(): int { return (int) static::getTranslationMessageWith( static::getTranslator(), 'first_day_of_week' ); } /** * Get the first day of week * * @return int */ public static function getWeekStartsAt() { if (static::$weekStartsAt === static::WEEK_DAY_AUTO) { return self::getFirstDayOfWeek(); } return static::$weekStartsAt; } /** * @deprecated To avoid conflict between different third-party libraries, static setters should not be used. * Use $weekEndsAt optional parameter instead when using endOfWeek method. You can also use the * 'first_day_of_week' locale setting to change the start of week according to current locale * selected and implicitly the end of week. * * Set the first day of week * * @param int|string $day week start day (or 'auto' to get the first day of week from Carbon::getLocale() culture). * * @return void */ public static function setWeekStartsAt($day) { static::$weekStartsAt = $day === static::WEEK_DAY_AUTO ? $day : max(0, (7 + $day) % 7); } /** * Get the last day of week * * @return int */ public static function getWeekEndsAt() { if (static::$weekStartsAt === static::WEEK_DAY_AUTO) { return (int) (static::DAYS_PER_WEEK - 1 + self::getFirstDayOfWeek()) % static::DAYS_PER_WEEK; } return static::$weekEndsAt; } /** * @deprecated To avoid conflict between different third-party libraries, static setters should not be used. * Use $weekStartsAt optional parameter instead when using startOfWeek, floorWeek, ceilWeek * or roundWeek method. You can also use the 'first_day_of_week' locale setting to change the * start of week according to current locale selected and implicitly the end of week. * * Set the last day of week * * @param int|string $day week end day (or 'auto' to get the day before the first day of week * from Carbon::getLocale() culture). * * @return void */ public static function setWeekEndsAt($day) { static::$weekEndsAt = $day === static::WEEK_DAY_AUTO ? $day : max(0, (7 + $day) % 7); } /** * Get weekend days * * @return array */ public static function getWeekendDays() { return static::$weekendDays; } /** * @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 * * @param array $days * * @return void */ public static function setWeekendDays($days) { static::$weekendDays = $days; } /** * Determine if a time string will produce a relative date. * * @param string $time * * @return bool true if time match a relative date, false if absolute or invalid time string */ public static function hasRelativeKeywords($time) { 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 ///////////////////////// /////////////////////////////////////////////////////////////////// /** * @deprecated To avoid conflict between different third-party libraries, static setters should not be used. * You should rather use UTF-8 language packages on every machine. * * Set if UTF8 will be used for localized date/time. * * @param bool $utf8 */ public static function setUtf8($utf8) { static::$utf8 = $utf8; } /** * Format the instance with the current locale. You can set the current * locale using setlocale() https://php.net/setlocale. * * @deprecated It uses OS language package and strftime() which is deprecated since PHP 8.1. * Use ->isoFormat() instead. * Deprecated since 2.55.0 * * @param string $format * * @return string */ public function formatLocalized($format) { // Check for Windows to find and replace the %e modifier correctly. if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { $format = preg_replace('#(?toDateTimeString()); $formatted = ($this->localStrictModeEnabled ?? static::isStrictModeEnabled()) ? strftime($format, $time) : @strftime($format, $time); return static::$utf8 ? ( \function_exists('mb_convert_encoding') ? mb_convert_encoding($formatted, 'UTF-8', mb_list_encodings()) : utf8_encode($formatted) ) : $formatted; } /** * Returns list of locale formats for ISO formatting. * * @param string|null $locale current locale used if null * * @return array */ public function getIsoFormats($locale = null) { return [ 'LT' => $this->getTranslationMessage('formats.LT', $locale, 'h:mm A'), 'LTS' => $this->getTranslationMessage('formats.LTS', $locale, 'h:mm:ss A'), 'L' => $this->getTranslationMessage('formats.L', $locale, 'MM/DD/YYYY'), 'LL' => $this->getTranslationMessage('formats.LL', $locale, 'MMMM D, YYYY'), 'LLL' => $this->getTranslationMessage('formats.LLL', $locale, 'MMMM D, YYYY h:mm A'), 'LLLL' => $this->getTranslationMessage('formats.LLLL', $locale, 'dddd, MMMM D, YYYY h:mm A'), '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 * * @return array */ public function getCalendarFormats($locale = null) { 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. * * @return array */ public static function getIsoUnits() { static $units = null; if ($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' => function (CarbonInterface $date, $originalFormat = null) { return $date->getTranslatedMinDayName($originalFormat); }, 'ddd' => function (CarbonInterface $date, $originalFormat = null) { return $date->getTranslatedShortDayName($originalFormat); }, 'dddd' => function (CarbonInterface $date, $originalFormat = null) { return $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' => function (CarbonInterface $date) { return (string) floor($date->micro / 100000); }, 'SS' => function (CarbonInterface $date) { return str_pad((string) floor($date->micro / 10000), 2, '0', STR_PAD_LEFT); }, 'SSS' => function (CarbonInterface $date) { return str_pad((string) floor($date->micro / 1000), 3, '0', STR_PAD_LEFT); }, 'SSSS' => function (CarbonInterface $date) { return str_pad((string) floor($date->micro / 100), 4, '0', STR_PAD_LEFT); }, 'SSSSS' => function (CarbonInterface $date) { return str_pad((string) floor($date->micro / 10), 5, '0', STR_PAD_LEFT); }, 'SSSSSS' => ['getPaddedUnit', ['micro', 6]], 'SSSSSSS' => function (CarbonInterface $date) { return str_pad((string) floor($date->micro * 10), 7, '0', STR_PAD_LEFT); }, 'SSSSSSSS' => function (CarbonInterface $date) { return str_pad((string) floor($date->micro * 100), 8, '0', STR_PAD_LEFT); }, 'SSSSSSSSS' => function (CarbonInterface $date) { return str_pad((string) floor($date->micro * 1000), 9, '0', STR_PAD_LEFT); }, 'M' => 'month', 'MM' => ['rawFormat', ['m']], 'MMM' => function (CarbonInterface $date, $originalFormat = null) { $month = $date->getTranslatedShortMonthName($originalFormat); $suffix = $date->getTranslationMessage('mmm_suffix'); if ($suffix && $month !== $date->monthName) { $month .= $suffix; } return $month; }, 'MMMM' => function (CarbonInterface $date, $originalFormat = null) { return $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' => function (CarbonInterface $date) { return ($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) * * @return string */ public function getPaddedUnit($unit, $length = 2, $padString = '0', $padType = STR_PAD_LEFT) { return ($this->$unit < 0 ? '-' : '').str_pad((string) abs($this->$unit), $length, $padString, $padType); } /** * Return a property with its ordinal. * * @param string $key * @param string|null $period * * @return string */ 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. * * @return string */ public function meridiem(bool $isLower = false): string { $hour = $this->hour; $index = $hour < 12 ? 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 * * @return string */ public function getAltNumber(string $key): string { return $this->translateNumber(\strlen($key) > 1 ? $this->$key : $this->rawFormat('h')); } /** * Format in the current language using ISO replacement patterns. * * @param string $format * @param string|null $originalFormat provide context if a chunk has been passed alone * * @return string */ public function isoFormat(string $format, ?string $originalFormat = null): string { $result = ''; $length = mb_strlen($format); $originalFormat = $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/', function ($code) { return 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 $e) { $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(). * * @return array */ public static function getFormatsToIsoReplacements() { static $replacements = null; if ($replacements === null) { $replacements = [ 'd' => true, 'D' => 'ddd', 'j' => true, 'l' => 'dddd', 'N' => true, 'S' => function ($date) { $day = $date->rawFormat('j'); return str_replace((string) $day, '', $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. * * @param string $format * * @return string */ 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) * * @return string */ public function getOffsetString($separator = ':') { $second = $this->getOffset(); $symbol = $second < 0 ? '-' : '+'; $minute = abs($second) / static::SECONDS_PER_MINUTE; $hour = str_pad((string) floor($minute / static::MINUTES_PER_HOUR), 2, '0', STR_PAD_LEFT); $minute = str_pad((string) (((int) $minute) % static::MINUTES_PER_HOUR), 2, '0', STR_PAD_LEFT); return "$symbol$hour$separator$minute"; } protected static function executeStaticCallable($macro, ...$parameters) { return static::bindMacroContext(null, function () use (&$macro, &$parameters) { if ($macro instanceof Closure) { $boundMacro = @Closure::bind($macro, null, static::class); return ($boundMacro ?: $macro)(...$parameters); } return $macro(...$parameters); }); } /** * Dynamically handle calls to the class. * * @param string $method magic method name called * @param array $parameters parameters list * * @throws BadMethodCallException * * @return mixed */ public static function __callStatic($method, $parameters) { if (!static::hasMacro($method)) { foreach (static::getGenericMacros() as $callback) { try { return static::executeStaticCallable($callback, $method, ...$parameters); } catch (BadMethodCallException $exception) { continue; } } if (static::isStrictModeEnabled()) { throw new UnknownMethodException(sprintf('%s::%s', static::class, $method)); } return null; } return static::executeStaticCallable(static::$globalMacros[$method], ...$parameters); } /** * Set specified unit to new given value. * * @param string $unit year, month, day, hour, minute, second or microsecond * @param int $value new value for given unit * * @return static */ public function setUnit($unit, $value = null) { $unit = static::singularUnit($unit); $dateUnits = ['year', 'month', 'day']; if (\in_array($unit, $dateUnits)) { return $this->setDate(...array_map(function ($name) use ($unit, $value) { return (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(function ($name) use ($unit, $value) { return (int) ($name === $unit ? $value : $this->$name); }, $units)); } /** * Returns standardized singular of a given singular/plural unit name (in English). * * @param string $unit * * @return string */ public static function singularUnit(string $unit): string { $unit = rtrim(mb_strtolower($unit), 's'); if ($unit === 'centurie') { return 'century'; } if ($unit === 'millennia') { return 'millennium'; } return $unit; } /** * Returns standardized plural of a given singular/plural unit name (in English). * * @param string $unit * * @return string */ public static function pluralUnit(string $unit): string { $unit = rtrim(strtolower($unit), 's'); if ($unit === 'century') { return 'centuries'; } if ($unit === 'millennium' || $unit === 'millennia') { return 'millennia'; } return "{$unit}s"; } protected function executeCallable($macro, ...$parameters) { if ($macro instanceof Closure) { $boundMacro = @$macro->bindTo($this, static::class) ?: @$macro->bindTo(null, static::class); return ($boundMacro ?: $macro)(...$parameters); } return $macro(...$parameters); } protected function executeCallableWithContext($macro, ...$parameters) { return static::bindMacroContext($this, function () use (&$macro, &$parameters) { return $this->executeCallable($macro, ...$parameters); }); } protected static function getGenericMacros() { foreach (static::$globalGenericMacros as $list) { foreach ($list as $macro) { yield $macro; } } } /** * Dynamically handle calls to the class. * * @param string $method magic method name called * @param array $parameters parameters list * * @throws UnknownMethodException|BadMethodCallException|ReflectionException|Throwable * * @return mixed */ public function __call($method, $parameters) { $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("/^(?$sizePattern)(?$syntaxPattern)DiffForHumans$/", $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); } $roundedValue = $this->callRoundMethod($method, $parameters); if ($roundedValue !== null) { return $roundedValue; } $unit = rtrim($method, 's'); if (str_starts_with($unit, 'is')) { $word = substr($unit, 2); if (\in_array($word, static::$days, true)) { return $this->isDayOfWeek($word); } switch ($word) { // @call is Check if the current instance has UTC timezone. (Both isUtc and isUTC cases are valid.) case 'Utc': case 'UTC': return $this->utc; // @call is Check if the current instance has non-UTC timezone. case 'Local': return $this->local; // @call is Check if the current instance is a valid date. case 'Valid': return $this->year !== 0; // @call is Check if the current instance is in a daylight saving time. case 'DST': return $this->dst; } } $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); if (str_starts_with($unit, 'Real')) { $unit = static::singularUnit(substr($unit, 4)); return $this->{"{$action}RealUnit"}($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); } $sixFirstLetters = substr($unit, 0, 6); $factor = -1; if ($sixFirstLetters === 'isLast') { $sixFirstLetters = 'isNext'; $factor = 1; } if ($sixFirstLetters === 'isNext') { $lowerUnit = strtolower(substr($unit, 6)); if (static::isModifiableUnit($lowerUnit)) { return $this->copy()->addUnit($lowerUnit, $factor, false)->isSameUnit($lowerUnit, ...$parameters); } } if ($sixFirstLetters === 'isSame') { try { return $this->isSameUnit(strtolower(substr($unit, 6)), ...$parameters); } catch (BadComparisonUnitException $exception) { // Try next } } if (str_starts_with($unit, 'isCurrent')) { try { return $this->isCurrentUnit(strtolower(substr($unit, 9))); } catch (BadComparisonUnitException | BadMethodCallException $exception) { // Try next } } 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 $exception) { // Try macros } } return static::bindMacroContext($this, function () use (&$method, &$parameters) { $macro = $this->getLocalMacro($method); if (!$macro) { foreach ([$this->localGenericMacros ?: [], static::getGenericMacros()] as $list) { foreach ($list as $callback) { try { return $this->executeCallable($callback, $method, ...$parameters); } catch (BadMethodCallException $exception) { continue; } } } if ($this->localStrictModeEnabled ?? static::isStrictModeEnabled()) { throw new UnknownMethodException($method); } return null; } return $this->executeCallable($macro, ...$parameters); }); } }