AC_services_website_design/system/I18n/TimeTrait.php

1198 lines
31 KiB
PHP
Raw Permalink Normal View History

2024-03-13 12:38:15 +00:00
<?php
/**
* This file is part of CodeIgniter 4 framework.
*
* (c) CodeIgniter Foundation <admin@codeigniter.com>
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace CodeIgniter\I18n;
use CodeIgniter\I18n\Exceptions\I18nException;
use DateInterval;
use DateTime;
use DateTimeImmutable;
use DateTimeInterface;
use DateTimeZone;
use Exception;
use IntlCalendar;
use IntlDateFormatter;
use Locale;
use ReturnTypeWillChange;
/**
* This trait has properties and methods for Time and TimeLegacy.
* When TimeLegacy is removed, this will be in Time.
*/
trait TimeTrait
{
/**
* @var DateTimeZone
*/
protected $timezone;
/**
* @var string
*/
protected $locale;
/**
* Format to use when displaying datetime through __toString
*
* @var string
*/
protected $toStringFormat = 'yyyy-MM-dd HH:mm:ss';
/**
* Used to check time string to determine if it is relative time or not....
*
* @var string
*/
protected static $relativePattern = '/this|next|last|tomorrow|yesterday|midnight|today|[+-]|first|last|ago/i';
/**
* @var DateTimeInterface|static|null
*/
protected static $testNow;
// --------------------------------------------------------------------
// Constructors
// --------------------------------------------------------------------
/**
* Time constructor.
*
* @param DateTimeZone|string|null $timezone
*
* @throws Exception
*/
public function __construct(?string $time = null, $timezone = null, ?string $locale = null)
{
$this->locale = $locale ?: Locale::getDefault();
$time ??= '';
// If a test instance has been provided, use it instead.
if ($time === '' && static::$testNow instanceof self) {
if ($timezone !== null) {
$testNow = static::$testNow->setTimezone($timezone);
$time = $testNow->format('Y-m-d H:i:s');
} else {
$timezone = static::$testNow->getTimezone();
$time = static::$testNow->format('Y-m-d H:i:s');
}
}
$timezone = $timezone ?: date_default_timezone_get();
$this->timezone = $timezone instanceof DateTimeZone ? $timezone : new DateTimeZone($timezone);
// If the time string was a relative string (i.e. 'next Tuesday')
// then we need to adjust the time going in so that we have a current
// timezone to work with.
if ($time !== '' && static::hasRelativeKeywords($time)) {
$instance = new DateTime('now', $this->timezone);
$instance->modify($time);
$time = $instance->format('Y-m-d H:i:s');
}
parent::__construct($time, $this->timezone);
}
/**
* Returns a new Time instance with the timezone set.
*
* @param DateTimeZone|string|null $timezone
*
* @return self
*
* @throws Exception
*/
public static function now($timezone = null, ?string $locale = null)
{
return new self(null, $timezone, $locale);
}
/**
* Returns a new Time instance while parsing a datetime string.
*
* Example:
* $time = Time::parse('first day of December 2008');
*
* @param DateTimeZone|string|null $timezone
*
* @return self
*
* @throws Exception
*/
public static function parse(string $datetime, $timezone = null, ?string $locale = null)
{
return new self($datetime, $timezone, $locale);
}
/**
* Return a new time with the time set to midnight.
*
* @param DateTimeZone|string|null $timezone
*
* @return self
*
* @throws Exception
*/
public static function today($timezone = null, ?string $locale = null)
{
return new self(date('Y-m-d 00:00:00'), $timezone, $locale);
}
/**
* Returns an instance set to midnight yesterday morning.
*
* @param DateTimeZone|string|null $timezone
*
* @return self
*
* @throws Exception
*/
public static function yesterday($timezone = null, ?string $locale = null)
{
return new self(date('Y-m-d 00:00:00', strtotime('-1 day')), $timezone, $locale);
}
/**
* Returns an instance set to midnight tomorrow morning.
*
* @param DateTimeZone|string|null $timezone
*
* @return self
*
* @throws Exception
*/
public static function tomorrow($timezone = null, ?string $locale = null)
{
return new self(date('Y-m-d 00:00:00', strtotime('+1 day')), $timezone, $locale);
}
/**
* Returns a new instance based on the year, month and day. If any of those three
* are left empty, will default to the current value.
*
* @param DateTimeZone|string|null $timezone
*
* @return self
*
* @throws Exception
*/
public static function createFromDate(?int $year = null, ?int $month = null, ?int $day = null, $timezone = null, ?string $locale = null)
{
return static::create($year, $month, $day, null, null, null, $timezone, $locale);
}
/**
* Returns a new instance with the date set to today, and the time set to the values passed in.
*
* @param DateTimeZone|string|null $timezone
*
* @return self
*
* @throws Exception
*/
public static function createFromTime(?int $hour = null, ?int $minutes = null, ?int $seconds = null, $timezone = null, ?string $locale = null)
{
return static::create(null, null, null, $hour, $minutes, $seconds, $timezone, $locale);
}
/**
* Returns a new instance with the date time values individually set.
*
* @param DateTimeZone|string|null $timezone
*
* @return self
*
* @throws Exception
*/
public static function create(
?int $year = null,
?int $month = null,
?int $day = null,
?int $hour = null,
?int $minutes = null,
?int $seconds = null,
$timezone = null,
?string $locale = null
) {
$year ??= date('Y');
$month ??= date('m');
$day ??= date('d');
$hour ??= 0;
$minutes ??= 0;
$seconds ??= 0;
return new self(date('Y-m-d H:i:s', strtotime("{$year}-{$month}-{$day} {$hour}:{$minutes}:{$seconds}")), $timezone, $locale);
}
/**
* Provides a replacement for DateTime's own createFromFormat function, that provides
* more flexible timeZone handling
*
* @param string $format
* @param string $datetime
* @param DateTimeZone|string|null $timezone
*
* @return self
*
* @throws Exception
*/
#[ReturnTypeWillChange]
public static function createFromFormat($format, $datetime, $timezone = null)
{
if (! $date = parent::createFromFormat($format, $datetime)) {
throw I18nException::forInvalidFormat($format);
}
return new self($date->format('Y-m-d H:i:s'), $timezone);
}
/**
* Returns a new instance with the datetime set based on the provided UNIX timestamp.
*
* @param DateTimeZone|string|null $timezone
*
* @return self
*
* @throws Exception
*/
public static function createFromTimestamp(int $timestamp, $timezone = null, ?string $locale = null)
{
$time = new self(gmdate('Y-m-d H:i:s', $timestamp), 'UTC', $locale);
$timezone ??= 'UTC';
return $time->setTimezone($timezone);
}
/**
* Takes an instance of DateTimeInterface and returns an instance of Time with it's same values.
*
* @return self
*
* @throws Exception
*/
public static function createFromInstance(DateTimeInterface $dateTime, ?string $locale = null)
{
$date = $dateTime->format('Y-m-d H:i:s');
$timezone = $dateTime->getTimezone();
return new self($date, $timezone, $locale);
}
/**
* Takes an instance of DateTime and returns an instance of Time with it's same values.
*
* @return self
*
* @throws Exception
*
* @deprecated Use createFromInstance() instead
*
* @codeCoverageIgnore
*/
public static function instance(DateTime $dateTime, ?string $locale = null)
{
return self::createFromInstance($dateTime, $locale);
}
/**
* Converts the current instance to a mutable DateTime object.
*
* @return DateTime
*
* @throws Exception
*/
public function toDateTime()
{
$dateTime = new DateTime('', $this->getTimezone());
$dateTime->setTimestamp(parent::getTimestamp());
return $dateTime;
}
// --------------------------------------------------------------------
// For Testing
// --------------------------------------------------------------------
/**
* Creates an instance of Time that will be returned during testing
* when calling 'Time::now()' instead of the current time.
*
* @param DateTimeInterface|self|string|null $datetime
* @param DateTimeZone|string|null $timezone
*
* @return void
*
* @throws Exception
*/
public static function setTestNow($datetime = null, $timezone = null, ?string $locale = null)
{
// Reset the test instance
if ($datetime === null) {
static::$testNow = null;
return;
}
// Convert to a Time instance
if (is_string($datetime)) {
$datetime = new self($datetime, $timezone, $locale);
} elseif ($datetime instanceof DateTimeInterface && ! $datetime instanceof self) {
$datetime = new self($datetime->format('Y-m-d H:i:s'), $timezone);
}
static::$testNow = $datetime;
}
/**
* Returns whether we have a testNow instance saved.
*/
public static function hasTestNow(): bool
{
return static::$testNow !== null;
}
// --------------------------------------------------------------------
// Getters
// --------------------------------------------------------------------
/**
* Returns the localized Year
*
* @throws Exception
*/
public function getYear(): string
{
return $this->toLocalizedString('y');
}
/**
* Returns the localized Month
*
* @throws Exception
*/
public function getMonth(): string
{
return $this->toLocalizedString('M');
}
/**
* Return the localized day of the month.
*
* @throws Exception
*/
public function getDay(): string
{
return $this->toLocalizedString('d');
}
/**
* Return the localized hour (in 24-hour format).
*
* @throws Exception
*/
public function getHour(): string
{
return $this->toLocalizedString('H');
}
/**
* Return the localized minutes in the hour.
*
* @throws Exception
*/
public function getMinute(): string
{
return $this->toLocalizedString('m');
}
/**
* Return the localized seconds
*
* @throws Exception
*/
public function getSecond(): string
{
return $this->toLocalizedString('s');
}
/**
* Return the index of the day of the week
*
* @throws Exception
*/
public function getDayOfWeek(): string
{
return $this->toLocalizedString('c');
}
/**
* Return the index of the day of the year
*
* @throws Exception
*/
public function getDayOfYear(): string
{
return $this->toLocalizedString('D');
}
/**
* Return the index of the week in the month
*
* @throws Exception
*/
public function getWeekOfMonth(): string
{
return $this->toLocalizedString('W');
}
/**
* Return the index of the week in the year
*
* @throws Exception
*/
public function getWeekOfYear(): string
{
return $this->toLocalizedString('w');
}
/**
* Returns the age in years from the date and 'now'
*
* @return int
*
* @throws Exception
*/
public function getAge()
{
// future dates have no age
return max(0, $this->difference(self::now())->getYears());
}
/**
* Returns the number of the current quarter for the year.
*
* @throws Exception
*/
public function getQuarter(): string
{
return $this->toLocalizedString('Q');
}
/**
* Are we in daylight savings time currently?
*/
public function getDst(): bool
{
return $this->format('I') === '1'; // 1 if Daylight Saving Time, 0 otherwise.
}
/**
* Returns boolean whether the passed timezone is the same as
* the local timezone.
*/
public function getLocal(): bool
{
$local = date_default_timezone_get();
return $local === $this->timezone->getName();
}
/**
* Returns boolean whether object is in UTC.
*/
public function getUtc(): bool
{
return $this->getOffset() === 0;
}
/**
* Returns the name of the current timezone.
*/
public function getTimezoneName(): string
{
return $this->timezone->getName();
}
// --------------------------------------------------------------------
// Setters
// --------------------------------------------------------------------
/**
* Sets the current year for this instance.
*
* @param int|string $value
*
* @return self
*
* @throws Exception
*/
public function setYear($value)
{
return $this->setValue('year', $value);
}
/**
* Sets the month of the year.
*
* @param int|string $value
*
* @return self
*
* @throws Exception
*/
public function setMonth($value)
{
if (is_numeric($value) && ($value < 1 || $value > 12)) {
throw I18nException::forInvalidMonth($value);
}
if (is_string($value) && ! is_numeric($value)) {
$value = date('m', strtotime("{$value} 1 2017"));
}
return $this->setValue('month', $value);
}
/**
* Sets the day of the month.
*
* @param int|string $value
*
* @return self
*
* @throws Exception
*/
public function setDay($value)
{
if ($value < 1 || $value > 31) {
throw I18nException::forInvalidDay($value);
}
$date = $this->getYear() . '-' . $this->getMonth();
$lastDay = date('t', strtotime($date));
if ($value > $lastDay) {
throw I18nException::forInvalidOverDay($lastDay, $value);
}
return $this->setValue('day', $value);
}
/**
* Sets the hour of the day (24 hour cycle)
*
* @param int|string $value
*
* @return self
*
* @throws Exception
*/
public function setHour($value)
{
if ($value < 0 || $value > 23) {
throw I18nException::forInvalidHour($value);
}
return $this->setValue('hour', $value);
}
/**
* Sets the minute of the hour
*
* @param int|string $value
*
* @return self
*
* @throws Exception
*/
public function setMinute($value)
{
if ($value < 0 || $value > 59) {
throw I18nException::forInvalidMinutes($value);
}
return $this->setValue('minute', $value);
}
/**
* Sets the second of the minute.
*
* @param int|string $value
*
* @return self
*
* @throws Exception
*/
public function setSecond($value)
{
if ($value < 0 || $value > 59) {
throw I18nException::forInvalidSeconds($value);
}
return $this->setValue('second', $value);
}
/**
* Helper method to do the heavy lifting of the 'setX' methods.
*
* @param int $value
*
* @return self
*
* @throws Exception
*/
protected function setValue(string $name, $value)
{
[$year, $month, $day, $hour, $minute, $second] = explode('-', $this->format('Y-n-j-G-i-s'));
${$name} = $value;
return self::create(
(int) $year,
(int) $month,
(int) $day,
(int) $hour,
(int) $minute,
(int) $second,
$this->getTimezoneName(),
$this->locale
);
}
/**
* Returns a new instance with the revised timezone.
*
* @param DateTimeZone|string $timezone
*
* @return self
*
* @throws Exception
*/
#[ReturnTypeWillChange]
public function setTimezone($timezone)
{
$timezone = $timezone instanceof DateTimeZone ? $timezone : new DateTimeZone($timezone);
return self::createFromInstance($this->toDateTime()->setTimezone($timezone), $this->locale);
}
/**
* Returns a new instance with the date set to the new timestamp.
*
* @param int $timestamp
*
* @return self
*
* @throws Exception
*/
#[ReturnTypeWillChange]
public function setTimestamp($timestamp)
{
$time = date('Y-m-d H:i:s', $timestamp);
return self::parse($time, $this->timezone, $this->locale);
}
// --------------------------------------------------------------------
// Add/Subtract
// --------------------------------------------------------------------
/**
* Returns a new Time instance with $seconds added to the time.
*
* @return static
*/
public function addSeconds(int $seconds)
{
$time = clone $this;
return $time->add(DateInterval::createFromDateString("{$seconds} seconds"));
}
/**
* Returns a new Time instance with $minutes added to the time.
*
* @return static
*/
public function addMinutes(int $minutes)
{
$time = clone $this;
return $time->add(DateInterval::createFromDateString("{$minutes} minutes"));
}
/**
* Returns a new Time instance with $hours added to the time.
*
* @return static
*/
public function addHours(int $hours)
{
$time = clone $this;
return $time->add(DateInterval::createFromDateString("{$hours} hours"));
}
/**
* Returns a new Time instance with $days added to the time.
*
* @return static
*/
public function addDays(int $days)
{
$time = clone $this;
return $time->add(DateInterval::createFromDateString("{$days} days"));
}
/**
* Returns a new Time instance with $months added to the time.
*
* @return static
*/
public function addMonths(int $months)
{
$time = clone $this;
return $time->add(DateInterval::createFromDateString("{$months} months"));
}
/**
* Returns a new Time instance with $years added to the time.
*
* @return static
*/
public function addYears(int $years)
{
$time = clone $this;
return $time->add(DateInterval::createFromDateString("{$years} years"));
}
/**
* Returns a new Time instance with $seconds subtracted from the time.
*
* @return static
*/
public function subSeconds(int $seconds)
{
$time = clone $this;
return $time->sub(DateInterval::createFromDateString("{$seconds} seconds"));
}
/**
* Returns a new Time instance with $minutes subtracted from the time.
*
* @return static
*/
public function subMinutes(int $minutes)
{
$time = clone $this;
return $time->sub(DateInterval::createFromDateString("{$minutes} minutes"));
}
/**
* Returns a new Time instance with $hours subtracted from the time.
*
* @return static
*/
public function subHours(int $hours)
{
$time = clone $this;
return $time->sub(DateInterval::createFromDateString("{$hours} hours"));
}
/**
* Returns a new Time instance with $days subtracted from the time.
*
* @return static
*/
public function subDays(int $days)
{
$time = clone $this;
return $time->sub(DateInterval::createFromDateString("{$days} days"));
}
/**
* Returns a new Time instance with $months subtracted from the time.
*
* @return static
*/
public function subMonths(int $months)
{
$time = clone $this;
return $time->sub(DateInterval::createFromDateString("{$months} months"));
}
/**
* Returns a new Time instance with $hours subtracted from the time.
*
* @return static
*/
public function subYears(int $years)
{
$time = clone $this;
return $time->sub(DateInterval::createFromDateString("{$years} years"));
}
// --------------------------------------------------------------------
// Formatters
// --------------------------------------------------------------------
/**
* Returns the localized value of the date in the format 'Y-m-d H:i:s'
*
* @return false|string
*
* @throws Exception
*/
public function toDateTimeString()
{
return $this->toLocalizedString('yyyy-MM-dd HH:mm:ss');
}
/**
* Returns a localized version of the date in Y-m-d format.
*
* @return string
*
* @throws Exception
*/
public function toDateString()
{
return $this->toLocalizedString('yyyy-MM-dd');
}
/**
* Returns a localized version of the date in nicer date format:
*
* i.e. Apr 1, 2017
*
* @return string
*
* @throws Exception
*/
public function toFormattedDateString()
{
return $this->toLocalizedString('MMM d, yyyy');
}
/**
* Returns a localized version of the time in nicer date format:
*
* i.e. 13:20:33
*
* @return string
*
* @throws Exception
*/
public function toTimeString()
{
return $this->toLocalizedString('HH:mm:ss');
}
/**
* Returns the localized value of this instance in $format.
*
* @return false|string
*
* @throws Exception
*/
public function toLocalizedString(?string $format = null)
{
$format ??= $this->toStringFormat;
return IntlDateFormatter::formatObject($this->toDateTime(), $format, $this->locale);
}
// --------------------------------------------------------------------
// Comparison
// --------------------------------------------------------------------
/**
* Determines if the datetime passed in is equal to the current instance.
* Equal in this case means that they represent the same moment in time,
* and are not required to be in the same timezone, as both times are
* converted to UTC and compared that way.
*
* @param DateTimeInterface|self|string $testTime
*
* @throws Exception
*/
public function equals($testTime, ?string $timezone = null): bool
{
$testTime = $this->getUTCObject($testTime, $timezone);
$ourTime = $this->toDateTime()
->setTimezone(new DateTimeZone('UTC'))
->format('Y-m-d H:i:s');
return $testTime->format('Y-m-d H:i:s') === $ourTime;
}
/**
* Ensures that the times are identical, taking timezone into account.
*
* @param DateTimeInterface|self|string $testTime
*
* @throws Exception
*/
public function sameAs($testTime, ?string $timezone = null): bool
{
if ($testTime instanceof DateTimeInterface) {
$testTime = $testTime->format('Y-m-d H:i:s');
} elseif (is_string($testTime)) {
$timezone = $timezone ?: $this->timezone;
$timezone = $timezone instanceof DateTimeZone ? $timezone : new DateTimeZone($timezone);
$testTime = new DateTime($testTime, $timezone);
$testTime = $testTime->format('Y-m-d H:i:s');
}
$ourTime = $this->toDateTimeString();
return $testTime === $ourTime;
}
/**
* Determines if the current instance's time is before $testTime,
* after converting to UTC.
*
* @param DateTimeInterface|self|string $testTime
*
* @throws Exception
*/
public function isBefore($testTime, ?string $timezone = null): bool
{
$testTime = $this->getUTCObject($testTime, $timezone)->getTimestamp();
$ourTime = $this->getTimestamp();
return $ourTime < $testTime;
}
/**
* Determines if the current instance's time is after $testTime,
* after converting in UTC.
*
* @param DateTimeInterface|self|string $testTime
*
* @throws Exception
*/
public function isAfter($testTime, ?string $timezone = null): bool
{
$testTime = $this->getUTCObject($testTime, $timezone)->getTimestamp();
$ourTime = $this->getTimestamp();
return $ourTime > $testTime;
}
// --------------------------------------------------------------------
// Differences
// --------------------------------------------------------------------
/**
* Returns a text string that is easily readable that describes
* how long ago, or how long from now, a date is, like:
*
* - 3 weeks ago
* - in 4 days
* - 6 hours ago
*
* @return string
*
* @throws Exception
*/
public function humanize()
{
$now = IntlCalendar::fromDateTime(self::now($this->timezone));
$time = $this->getCalendar()->getTime();
$years = $now->fieldDifference($time, IntlCalendar::FIELD_YEAR);
$months = $now->fieldDifference($time, IntlCalendar::FIELD_MONTH);
$days = $now->fieldDifference($time, IntlCalendar::FIELD_DAY_OF_YEAR);
$hours = $now->fieldDifference($time, IntlCalendar::FIELD_HOUR_OF_DAY);
$minutes = $now->fieldDifference($time, IntlCalendar::FIELD_MINUTE);
$phrase = null;
if ($years !== 0) {
$phrase = lang('Time.years', [abs($years)]);
$before = $years < 0;
} elseif ($months !== 0) {
$phrase = lang('Time.months', [abs($months)]);
$before = $months < 0;
} elseif ($days !== 0 && (abs($days) >= 7)) {
$weeks = ceil($days / 7);
$phrase = lang('Time.weeks', [abs($weeks)]);
$before = $days < 0;
} elseif ($days !== 0) {
$before = $days < 0;
// Yesterday/Tomorrow special cases
if (abs($days) === 1) {
return $before ? lang('Time.yesterday') : lang('Time.tomorrow');
}
$phrase = lang('Time.days', [abs($days)]);
} elseif ($hours !== 0) {
$phrase = lang('Time.hours', [abs($hours)]);
$before = $hours < 0;
} elseif ($minutes !== 0) {
$phrase = lang('Time.minutes', [abs($minutes)]);
$before = $minutes < 0;
} else {
return lang('Time.now');
}
return $before ? lang('Time.ago', [$phrase]) : lang('Time.inFuture', [$phrase]);
}
/**
* @param DateTimeInterface|self|string $testTime
*
* @return TimeDifference
*
* @throws Exception
*/
public function difference($testTime, ?string $timezone = null)
{
$testTime = $this->getUTCObject($testTime, $timezone);
$ourTime = $this->getUTCObject($this);
return new TimeDifference($ourTime, $testTime);
}
// --------------------------------------------------------------------
// Utilities
// --------------------------------------------------------------------
/**
* Returns a Time instance with the timezone converted to UTC.
*
* @param DateTimeInterface|self|string $time
*
* @return DateTime|static
*
* @throws Exception
*/
public function getUTCObject($time, ?string $timezone = null)
{
if ($time instanceof self) {
$time = $time->toDateTime();
} elseif (is_string($time)) {
$timezone = $timezone ?: $this->timezone;
$timezone = $timezone instanceof DateTimeZone ? $timezone : new DateTimeZone($timezone);
$time = new DateTime($time, $timezone);
}
if ($time instanceof DateTime || $time instanceof DateTimeImmutable) {
$time = $time->setTimezone(new DateTimeZone('UTC'));
}
return $time;
}
/**
* Returns the IntlCalendar object used for this object,
* taking into account the locale, date, etc.
*
* Primarily used internally to provide the difference and comparison functions,
* but available for public consumption if they need it.
*
* @return IntlCalendar
*
* @throws Exception
*/
public function getCalendar()
{
return IntlCalendar::fromDateTime($this);
}
/**
* Check a time string to see if it includes a relative date (like 'next Tuesday').
*/
protected static function hasRelativeKeywords(string $time): bool
{
// skip common format with a '-' in it
if (preg_match('/\d{4}-\d{1,2}-\d{1,2}/', $time) !== 1) {
return preg_match(static::$relativePattern, $time) > 0;
}
return false;
}
/**
* Outputs a short format version of the datetime.
* The output is NOT localized intentionally.
*/
public function __toString(): string
{
return $this->format('Y-m-d H:i:s');
}
/**
* Allow for property-type access to any getX method...
*
* Note that we cannot use this for any of our setX methods,
* as they return new Time objects, but the __set ignores
* return values.
* See http://php.net/manual/en/language.oop5.overloading.php
*
* @param string $name
*
* @return array|bool|DateTimeInterface|DateTimeZone|int|intlCalendar|self|string|null
*/
public function __get($name)
{
$method = 'get' . ucfirst($name);
if (method_exists($this, $method)) {
return $this->{$method}();
}
return null;
}
/**
* Allow for property-type checking to any getX method...
*
* @param string $name
*/
public function __isset($name): bool
{
$method = 'get' . ucfirst($name);
return method_exists($this, $method);
}
/**
* This is called when we unserialize the Time object.
*/
public function __wakeup(): void
{
/**
* Prior to unserialization, this is a string.
*
* @var string $timezone
*/
$timezone = $this->timezone;
$this->timezone = new DateTimeZone($timezone);
// @phpstan-ignore-next-line `$this->date` is a special property for PHP internal use.
parent::__construct($this->date, $this->timezone);
}
}