芝麻web文件管理V1.00
编辑当前文件:/home/pulsehostuk9/public_html/invoicer.pulsehost.co.uk/vendor/nesbot/carbon/src/Carbon/Factory.php
* * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Carbon; use Closure; use DateTimeImmutable; use DateTimeInterface; use DateTimeZone; use InvalidArgumentException; use ReflectionMethod; use RuntimeException; use Symfony\Contracts\Translation\TranslatorInterface; use Throwable; /** * A factory to generate Carbon instances with common settings. * *
* * @method bool canBeCreatedFromFormat(?string $date, string $format) Checks if the (date)time string is in a given format and valid to create a * new instance. * @method ?Carbon create($year = 0, $month = 1, $day = 1, $hour = 0, $minute = 0, $second = 0, $timezone = null) Create a new Carbon instance from a specific date and time. * If any of $year, $month or $day are set to null their now() values will * be used. * If $hour is null it will be set to its now() value and the default * values for $minute and $second will be their now() values. * If $hour is not null then the default values for $minute and $second * will be 0. * @method Carbon createFromDate($year = null, $month = null, $day = null, $timezone = null) Create a Carbon instance from just a date. The time portion is set to now. * @method ?Carbon createFromFormat($format, $time, $timezone = null) Create a Carbon instance from a specific format. * @method ?Carbon createFromIsoFormat(string $format, string $time, $timezone = null, ?string $locale = 'en', ?TranslatorInterface $translator = null) Create a Carbon instance from a specific ISO format (same replacements as ->isoFormat()). * @method ?Carbon createFromLocaleFormat(string $format, string $locale, string $time, $timezone = null) Create a Carbon instance from a specific format and a string in a given language. * @method ?Carbon createFromLocaleIsoFormat(string $format, string $locale, string $time, $timezone = null) Create a Carbon instance from a specific ISO format and a string in a given language. * @method Carbon createFromTime($hour = 0, $minute = 0, $second = 0, $timezone = null) Create a Carbon instance from just a time. The date portion is set to today. * @method Carbon createFromTimeString(string $time, DateTimeZone|string|int|null $timezone = null) Create a Carbon instance from a time string. The date portion is set to today. * @method Carbon createFromTimestamp(string|int|float $timestamp, DateTimeZone|string|int|null $timezone = null) Create a Carbon instance from a timestamp and set the timezone (UTC by default). * Timestamp input can be given as int, float or a string containing one or more numbers. * @method Carbon createFromTimestampMs(string|int|float $timestamp, DateTimeZone|string|int|null $timezone = null) Create a Carbon instance from a timestamp in milliseconds. * Timestamp input can be given as int, float or a string containing one or more numbers. * @method Carbon createFromTimestampMsUTC($timestamp) Create a Carbon instance from a timestamp in milliseconds. * Timestamp input can be given as int, float or a string containing one or more numbers. * @method Carbon createFromTimestampUTC(string|int|float $timestamp) Create a Carbon instance from a timestamp keeping the timezone to UTC. * Timestamp input can be given as int, float or a string containing one or more numbers. * @method Carbon createMidnightDate($year = null, $month = null, $day = null, $timezone = null) Create a Carbon instance from just a date. The time portion is set to midnight. * @method ?Carbon createSafe($year = null, $month = null, $day = null, $hour = null, $minute = null, $second = null, $timezone = null) Create a new safe Carbon instance from a specific date and time. * If any of $year, $month or $day are set to null their now() values will * be used. * If $hour is null it will be set to its now() value and the default * values for $minute and $second will be their now() values. * If $hour is not null then the default values for $minute and $second * will be 0. * If one of the set values is not valid, an InvalidDateException * will be thrown. * @method Carbon createStrict(?int $year = 0, ?int $month = 1, ?int $day = 1, ?int $hour = 0, ?int $minute = 0, ?int $second = 0, $timezone = null) Create a new Carbon instance from a specific date and time using strict validation. * @method mixed executeWithLocale(string $locale, callable $func) Set the current locale to the given, execute the passed function, reset the locale to previous one, * then return the result of the closure (or null if the closure was void). * @method Carbon fromSerialized($value) Create an instance from a serialized string. * @method array getAvailableLocales() Returns the list of internally available locales and already loaded custom locales. * (It will ignore custom translator dynamic loading.) * @method Language[] getAvailableLocalesInfo() Returns list of Language object for each available locale. This object allow you to get the ISO name, native * name, region and variant of the locale. * @method array getDays() Get the days of the week. * @method ?string getFallbackLocale() Get the fallback locale. * @method array getFormatsToIsoReplacements() List of replacements from date() format to isoFormat(). * @method array getIsoUnits() Returns list of locale units for ISO formatting. * @method array|false getLastErrors() {@inheritdoc} * @method string getLocale() Get the current translator locale. * @method int getMidDayAt() get midday/noon hour * @method string getTimeFormatByPrecision(string $unitPrecision) Return a format from H:i to H:i:s.u according to given unit precision. * @method string|Closure|null getTranslationMessageWith($translator, string $key, ?string $locale = null, ?string $default = null) Returns raw translation message for a given key. * @method int getWeekEndsAt(?string $locale = null) Get the last day of week. * @method int getWeekStartsAt(?string $locale = null) Get the first day of week. * @method bool hasRelativeKeywords(?string $time) Determine if a time string will produce a relative date. * @method Carbon instance(DateTimeInterface $date) Create a Carbon instance from a DateTime one. * @method bool isImmutable() Returns true if the current class/instance is immutable. * @method bool isModifiableUnit($unit) Returns true if a property can be changed via setter. * @method bool isMutable() Returns true if the current class/instance is mutable. * @method bool localeHasDiffOneDayWords(string $locale) Returns true if the given locale is internally supported and has words for 1-day diff (just now, yesterday, tomorrow). * Support is considered enabled if the 3 words are translated in the given locale. * @method bool localeHasDiffSyntax(string $locale) Returns true if the given locale is internally supported and has diff syntax support (ago, from now, before, after). * Support is considered enabled if the 4 sentences are translated in the given locale. * @method bool localeHasDiffTwoDayWords(string $locale) Returns true if the given locale is internally supported and has words for 2-days diff (before yesterday, after tomorrow). * Support is considered enabled if the 2 words are translated in the given locale. * @method bool localeHasPeriodSyntax($locale) Returns true if the given locale is internally supported and has period syntax support (X times, every X, from X, to X). * Support is considered enabled if the 4 sentences are translated in the given locale. * @method bool localeHasShortUnits(string $locale) Returns true if the given locale is internally supported and has short-units support. * Support is considered enabled if either year, day or hour has a short variant translated. * @method ?Carbon make($var) Make a Carbon instance from given variable if possible. * Always return a new instance. Parse only strings and only these likely to be dates (skip intervals * and recurrences). Throw an exception for invalid format, but otherwise return null. * @method void mixin(object|string $mixin) Mix another object into the class. * @method Carbon now(DateTimeZone|string|int|null $timezone = null) Get a Carbon instance for the current date and time. * @method Carbon parse(DateTimeInterface|WeekDay|Month|string|int|float|null $time, DateTimeZone|string|int|null $timezone = null) Create a carbon instance from a string. * This is an alias for the constructor that allows better fluent syntax * as it allows you to do Carbon::parse('Monday next week')->fn() rather * than (new Carbon('Monday next week'))->fn(). * @method Carbon parseFromLocale(string $time, ?string $locale = null, DateTimeZone|string|int|null $timezone = null) Create a carbon instance from a localized string (in French, Japanese, Arabic, etc.). * @method string pluralUnit(string $unit) Returns standardized plural of a given singular/plural unit name (in English). * @method ?Carbon rawCreateFromFormat(string $format, string $time, $timezone = null) Create a Carbon instance from a specific format. * @method Carbon rawParse(DateTimeInterface|WeekDay|Month|string|int|float|null $time, DateTimeZone|string|int|null $timezone = null) Create a carbon instance from a string. * This is an alias for the constructor that allows better fluent syntax * as it allows you to do Carbon::parse('Monday next week')->fn() rather * than (new Carbon('Monday next week'))->fn(). * @method void setFallbackLocale(string $locale) Set the fallback locale. * @method void setLocale(string $locale) Set the current translator locale and indicate if the source locale file exists. * Pass 'auto' as locale to use the closest language to the current LC_TIME locale. * @method void setMidDayAt($hour) @deprecated To avoid conflict between different third-party libraries, static setters should not be used. * You should rather consider mid-day is always 12pm, then if you need to test if it's an other * hour, test it explicitly: * $date->format('G') == 13 * or to set explicitly to a given hour: * $date->setTime(13, 0, 0, 0) * Set midday/noon hour * @method string singularUnit(string $unit) Returns standardized singular of a given singular/plural unit name (in English). * @method void sleep(int|float $seconds) * @method Carbon today(DateTimeZone|string|int|null $timezone = null) Create a Carbon instance for today. * @method Carbon tomorrow(DateTimeZone|string|int|null $timezone = null) Create a Carbon instance for tomorrow. * @method string translateTimeString(string $timeString, ?string $from = null, ?string $to = null, int $mode = CarbonInterface::TRANSLATE_ALL) Translate a time string from a locale to an other. * @method string translateWith(TranslatorInterface $translator, string $key, array $parameters = [], $number = null) Translate using translation string or callback available. * @method Carbon yesterday(DateTimeZone|string|int|null $timezone = null) Create a Carbon instance for yesterday. * *
*/ class Factory { protected string $className = Carbon::class; protected array $settings = []; /** * A test Carbon instance to be returned when now instances are created. */ protected Closure|CarbonInterface|null $testNow = null; /** * The timezone to restore to when clearing the time mock. */ protected ?string $testDefaultTimezone = null; /** * Is true when test-now is generated by a closure and timezone should be taken on the fly from it. */ protected bool $useTimezoneFromTestNow = false; /** * Default translator. */ protected TranslatorInterface $translator; /** * Days of weekend. */ protected array $weekendDays = [ CarbonInterface::SATURDAY, CarbonInterface::SUNDAY, ]; /** * Format regex patterns. * * @var array
*/ protected array $regexFormats = [ 'd' => '(3[01]|[12][0-9]|0[1-9])', 'D' => '(Sun|Mon|Tue|Wed|Thu|Fri|Sat)', 'j' => '([123][0-9]|[1-9])', 'l' => '([a-zA-Z]{2,})', 'N' => '([1-7])', 'S' => '(st|nd|rd|th)', 'w' => '([0-6])', 'z' => '(36[0-5]|3[0-5][0-9]|[12][0-9]{2}|[1-9]?[0-9])', 'W' => '(5[012]|[1-4][0-9]|0?[1-9])', 'F' => '([a-zA-Z]{2,})', 'm' => '(1[012]|0[1-9])', 'M' => '([a-zA-Z]{3})', 'n' => '(1[012]|[1-9])', 't' => '(2[89]|3[01])', 'L' => '(0|1)', 'o' => '([1-9][0-9]{0,4})', 'Y' => '([1-9]?[0-9]{4})', 'y' => '([0-9]{2})', 'a' => '(am|pm)', 'A' => '(AM|PM)', 'B' => '([0-9]{3})', 'g' => '(1[012]|[1-9])', 'G' => '(2[0-3]|1?[0-9])', 'h' => '(1[012]|0[1-9])', 'H' => '(2[0-3]|[01][0-9])', 'i' => '([0-5][0-9])', 's' => '([0-5][0-9])', 'u' => '([0-9]{1,6})', 'v' => '([0-9]{1,3})', 'e' => '([a-zA-Z]{1,5})|([a-zA-Z]*\\/[a-zA-Z]*)', 'I' => '(0|1)', 'O' => '([+-](1[012]|0[0-9])[0134][05])', 'P' => '([+-](1[012]|0[0-9]):[0134][05])', 'p' => '(Z|[+-](1[012]|0[0-9]):[0134][05])', 'T' => '([a-zA-Z]{1,5})', 'Z' => '(-?[1-5]?[0-9]{1,4})', 'U' => '([0-9]*)', // The formats below are combinations of the above formats. 'c' => '(([1-9]?[0-9]{4})-(1[012]|0[1-9])-(3[01]|[12][0-9]|0[1-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])[+-](1[012]|0[0-9]):([0134][05]))', // Y-m-dTH:i:sP 'r' => '(([a-zA-Z]{3}), ([123][0-9]|0[1-9]) ([a-zA-Z]{3}) ([1-9]?[0-9]{4}) (2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9]) [+-](1[012]|0[0-9])([0134][05]))', // D, d M Y H:i:s O ]; /** * Format modifiers (such as available in createFromFormat) regex patterns. * * @var array */ protected array $regexFormatModifiers = [ '*' => '.+', ' ' => '[ ]', '#' => '[;:\\/.,()-]', '?' => '([^a]|[a])', '!' => '', '|' => '', '+' => '', ]; public function __construct(array $settings = [], ?string $className = null) { if ($className) { $this->className = $className; } $this->settings = $settings; } public function getClassName(): string { return $this->className; } public function setClassName(string $className): self { $this->className = $className; return $this; } public function className(?string $className = null): self|string { return $className === null ? $this->getClassName() : $this->setClassName($className); } public function getSettings(): array { return $this->settings; } public function setSettings(array $settings): self { $this->settings = $settings; return $this; } public function settings(?array $settings = null): self|array { return $settings === null ? $this->getSettings() : $this->setSettings($settings); } public function mergeSettings(array $settings): self { $this->settings = array_merge($this->settings, $settings); return $this; } public function setHumanDiffOptions(int $humanDiffOptions): void { $this->mergeSettings([ 'humanDiffOptions' => $humanDiffOptions, ]); } public function enableHumanDiffOption($humanDiffOption): void { $this->setHumanDiffOptions($this->getHumanDiffOptions() | $humanDiffOption); } public function disableHumanDiffOption(int $humanDiffOption): void { $this->setHumanDiffOptions($this->getHumanDiffOptions() & ~$humanDiffOption); } public function getHumanDiffOptions(): int { return (int) ($this->getSettings()['humanDiffOptions'] ?? 0); } /** * Register a custom macro. * * Pass null macro to remove it. * * @example * ``` * $userSettings = [ * 'locale' => 'pt', * 'timezone' => 'America/Sao_Paulo', * ]; * $factory->macro('userFormat', function () use ($userSettings) { * return $this->copy()->locale($userSettings['locale'])->tz($userSettings['timezone'])->calendar(); * }); * echo $factory->yesterday()->hours(11)->userFormat(); * ``` */ public function macro(string $name, ?callable $macro): void { $macros = $this->getSettings()['macros'] ?? []; $macros[$name] = $macro; $this->mergeSettings([ 'macros' => $macros, ]); } /** * Remove all macros and generic macros. */ public function resetMacros(): void { $this->mergeSettings([ 'macros' => null, 'genericMacros' => null, ]); } /** * Register a custom macro. * * @param callable $macro * @param int $priority marco with higher priority is tried first * * @return void */ public function genericMacro(callable $macro, int $priority = 0): void { $genericMacros = $this->getSettings()['genericMacros'] ?? []; if (!isset($genericMacros[$priority])) { $genericMacros[$priority] = []; krsort($genericMacros, SORT_NUMERIC); } $genericMacros[$priority][] = $macro; $this->mergeSettings([ 'genericMacros' => $genericMacros, ]); } /** * Checks if macro is registered globally. */ public function hasMacro(string $name): bool { return isset($this->getSettings()['macros'][$name]); } /** * Get the raw callable macro registered globally for a given name. */ public function getMacro(string $name): ?callable { return $this->getSettings()['macros'][$name] ?? null; } /** * Set the default translator instance to use. */ public function setTranslator(TranslatorInterface $translator): void { $this->translator = $translator; } /** * Initialize the default translator instance if necessary. */ public function getTranslator(): TranslatorInterface { return $this->translator ??= Translator::get(); } /** * Reset the format used to the default when type juggling a Carbon instance to a string * * @return void */ public function resetToStringFormat(): void { $this->setToStringFormat(null); } /** * Set the default format used when type juggling a Carbon instance to a string. */ public function setToStringFormat(string|Closure|null $format): void { $this->mergeSettings([ 'toStringFormat' => $format, ]); } /** * JSON serialize all Carbon instances using the given callback. */ public function serializeUsing(string|callable|null $format): void { $this->mergeSettings([ 'toJsonFormat' => $format, ]); } /** * Enable the strict mode (or disable with passing false). */ public function useStrictMode(bool $strictModeEnabled = true): void { $this->mergeSettings([ 'strictMode' => $strictModeEnabled, ]); } /** * Returns true if the strict mode is globally in use, false else. * (It can be overridden in specific instances.) */ public function isStrictModeEnabled(): bool { return $this->getSettings()['strictMode'] ?? true; } /** * Indicates if months should be calculated with overflow. */ public function useMonthsOverflow(bool $monthsOverflow = true): void { $this->mergeSettings([ 'monthOverflow' => $monthsOverflow, ]); } /** * Reset the month overflow behavior. */ public function resetMonthsOverflow(): void { $this->useMonthsOverflow(); } /** * Get the month overflow global behavior (can be overridden in specific instances). */ public function shouldOverflowMonths(): bool { return $this->getSettings()['monthOverflow'] ?? true; } /** * Indicates if years should be calculated with overflow. */ public function useYearsOverflow(bool $yearsOverflow = true): void { $this->mergeSettings([ 'yearOverflow' => $yearsOverflow, ]); } /** * Reset the month overflow behavior. */ public function resetYearsOverflow(): void { $this->useYearsOverflow(); } /** * Get the month overflow global behavior (can be overridden in specific instances). */ public function shouldOverflowYears(): bool { return $this->getSettings()['yearOverflow'] ?? true; } /** * Get weekend days * * @return array */ public function getWeekendDays(): array { return $this->weekendDays; } /** * Set weekend days */ public function setWeekendDays(array $days): void { $this->weekendDays = $days; } /** * Checks if the (date)time string is in a given format. * * @example * ``` * Carbon::hasFormat('11:12:45', 'h:i:s'); // true * Carbon::hasFormat('13:12:45', 'h:i:s'); // false * ``` */ public function hasFormat(string $date, string $format): bool { // createFromFormat() is known to handle edge cases silently. // E.g. "1975-5-1" (Y-n-j) will still be parsed correctly when "Y-m-d" is supplied as the format. // To ensure we're really testing against our desired format, perform an additional regex validation. return $this->matchFormatPattern($date, preg_quote($format, '/'), $this->regexFormats); } /** * Checks if the (date)time string is in a given format. * * @example * ``` * Carbon::hasFormatWithModifiers('31/08/2015', 'd#m#Y'); // true * Carbon::hasFormatWithModifiers('31/08/2015', 'm#d#Y'); // false * ``` */ public function hasFormatWithModifiers(string $date, string $format): bool { return $this->matchFormatPattern($date, $format, array_merge($this->regexFormats, $this->regexFormatModifiers)); } /** * Set a Carbon instance (real or mock) to be returned when a "now" * instance is created. The provided instance will be returned * specifically under the following conditions: * - A call to the static now() method, ex. Carbon::now() * - When a null (or blank string) is passed to the constructor or parse(), ex. new Carbon(null) * - When the string "now" is passed to the constructor or parse(), ex. new Carbon('now') * - When a string containing the desired time is passed to Carbon::parse(). * * Note the timezone parameter was left out of the examples above and * has no affect as the mock value will be returned regardless of its value. * * Only the moment is mocked with setTestNow(), the timezone will still be the one passed * as parameter of date_default_timezone_get() as a fallback (see setTestNowAndTimezone()). * * To clear the test instance call this method using the default * parameter of null. * * /!\ Use this method for unit tests only. * * @param DateTimeInterface|Closure|static|string|false|null $testNow real or mock Carbon instance */ public function setTestNow(mixed $testNow = null): void { $this->useTimezoneFromTestNow = false; $this->testNow = $testNow instanceof self || $testNow instanceof Closure ? $testNow : $this->make($testNow); } /** * Set a Carbon instance (real or mock) to be returned when a "now" * instance is created. The provided instance will be returned * specifically under the following conditions: * - A call to the static now() method, ex. Carbon::now() * - When a null (or blank string) is passed to the constructor or parse(), ex. new Carbon(null) * - When the string "now" is passed to the constructor or parse(), ex. new Carbon('now') * - When a string containing the desired time is passed to Carbon::parse(). * * It will also align default timezone (e.g. call date_default_timezone_set()) with * the second argument or if null, with the timezone of the given date object. * * To clear the test instance call this method using the default * parameter of null. * * /!\ Use this method for unit tests only. * * @param DateTimeInterface|Closure|static|string|false|null $testNow real or mock Carbon instance */ public function setTestNowAndTimezone(mixed $testNow = null, $timezone = null): void { if ($testNow) { $this->testDefaultTimezone ??= date_default_timezone_get(); } $useDateInstanceTimezone = $testNow instanceof DateTimeInterface; if ($useDateInstanceTimezone) { $this->setDefaultTimezone($testNow->getTimezone()->getName(), $testNow); } $this->setTestNow($testNow); $this->useTimezoneFromTestNow = ($timezone === null && $testNow instanceof Closure); if (!$useDateInstanceTimezone) { $now = $this->getMockedTestNow(\func_num_args() === 1 ? null : $timezone); $this->setDefaultTimezone($now?->tzName ?? $this->testDefaultTimezone ?? 'UTC', $now); } if (!$testNow) { $this->testDefaultTimezone = null; } } /** * Temporarily sets a static date to be used within the callback. * Using setTestNow to set the date, executing the callback, then * clearing the test instance. * * /!\ Use this method for unit tests only. * * @template T * * @param DateTimeInterface|Closure|static|string|false|null $testNow real or mock Carbon instance * @param Closure(): T $callback * * @return T */ public function withTestNow(mixed $testNow, callable $callback): mixed { $this->setTestNow($testNow); try { $result = $callback(); } finally { $this->setTestNow(); } return $result; } /** * Get the Carbon instance (real or mock) to be returned when a "now" * instance is created. * * @return Closure|CarbonInterface|null the current instance used for testing */ public function getTestNow(): Closure|CarbonInterface|null { if ($this->testNow === null) { $factory = FactoryImmutable::getDefaultInstance(); if ($factory !== $this) { return $factory->getTestNow(); } } return $this->testNow; } public function handleTestNowClosure( Closure|CarbonInterface|null $testNow, DateTimeZone|string|int|null $timezone = null, ): ?CarbonInterface { if ($testNow instanceof Closure) { $callback = Callback::fromClosure($testNow); $realNow = new DateTimeImmutable('now'); $testNow = $testNow($callback->prepareParameter($this->parse( $realNow->format('Y-m-d H:i:s.u'), $timezone ?? $realNow->getTimezone(), ))); if ($testNow !== null && !($testNow instanceof DateTimeInterface)) { $function = $callback->getReflectionFunction(); $type = \is_object($testNow) ? $testNow::class : \gettype($testNow); throw new RuntimeException( 'The test closure defined in '.$function->getFileName(). ' at line '.$function->getStartLine().' returned '.$type. '; expected '.CarbonInterface::class.'|null', ); } if (!($testNow instanceof CarbonInterface)) { $timezone ??= $this->useTimezoneFromTestNow ? $testNow->getTimezone() : null; $testNow = $this->__call('instance', [$testNow, $timezone]); } } return $testNow; } /** * Determine if there is a valid test instance set. A valid test instance * is anything that is not null. * * @return bool true if there is a test instance, otherwise false */ public function hasTestNow(): bool { return $this->getTestNow() !== null; } public function withTimeZone(DateTimeZone|string|int|null $timezone): static { $factory = clone $this; $factory->settings['timezone'] = $timezone; return $factory; } public function __call(string $name, array $arguments): mixed { $method = new ReflectionMethod($this->className, $name); $settings = $this->settings; if ($settings && isset($settings['timezone'])) { $timezoneParameters = array_filter($method->getParameters(), function ($parameter) { return \in_array($parameter->getName(), ['tz', 'timezone'], true); }); $timezoneSetting = $settings['timezone']; if (isset($arguments[0]) && \in_array($name, ['instance', 'make', 'create', 'parse'], true)) { if ($arguments[0] instanceof DateTimeInterface) { $settings['innerTimezone'] = $settings['timezone']; } elseif (\is_string($arguments[0]) && date_parse($arguments[0])['is_localtime']) { unset($settings['timezone'], $settings['innerTimezone']); } } if (\count($timezoneParameters)) { $index = key($timezoneParameters); if (!isset($arguments[$index])) { array_splice($arguments, key($timezoneParameters), 0, [$timezoneSetting]); } unset($settings['timezone']); } } $clock = FactoryImmutable::getCurrentClock(); FactoryImmutable::setCurrentClock($this); try { $result = $this->className::$name(...$arguments); } finally { FactoryImmutable::setCurrentClock($clock); } if (isset($this->translator)) { $settings['translator'] = $this->translator; } return $result instanceof CarbonInterface && !empty($settings) ? $result->settings($settings) : $result; } /** * Get the mocked date passed in setTestNow() and if it's a Closure, execute it. */ protected function getMockedTestNow(DateTimeZone|string|int|null $timezone): ?CarbonInterface { $testNow = $this->handleTestNowClosure($this->getTestNow()); if ($testNow instanceof CarbonInterface) { $testNow = $testNow->avoidMutation(); if ($timezone !== null) { return $testNow->setTimezone($timezone); } } return $testNow; } /** * Checks if the (date)time string is in a given format with * given list of pattern replacements. * * @example * ``` * Carbon::hasFormat('11:12:45', 'h:i:s'); // true * Carbon::hasFormat('13:12:45', 'h:i:s'); // false * ``` * * @param string $date * @param string $format * @param array $replacements * * @return bool */ private function matchFormatPattern(string $date, string $format, array $replacements): bool { // Preg quote, but remove escaped backslashes since we'll deal with escaped characters in the format string. $regex = str_replace('\\\\', '\\', $format); // Replace not-escaped letters $regex = preg_replace_callback( '/(? $match[1].strtr($match[2], $replacements), $regex, ); // Replace escaped letters by the letter itself $regex = preg_replace('/(?toRegionName($date); throw new InvalidArgumentException( "Timezone ID '$timezone' is invalid". ($suggestion && $suggestion !== $timezone ? ", did you mean '$suggestion'?" : '.')."\n". "It must be one of the IDs from DateTimeZone::listIdentifiers(),\n". 'For the record, hours/minutes offset are relevant only for a particular moment, '. 'but not as a default timezone.', 0, $previous ); } } }