Browse Source

Support Chronos extending DateTimeImmutable

Corey Taylor 2 years ago
parent
commit
ead848b3ad

+ 1 - 1
composer.json

@@ -26,7 +26,7 @@
         "ext-intl": "*",
         "ext-json": "*",
         "ext-mbstring": "*",
-        "cakephp/chronos": "^3.0",
+        "cakephp/chronos": "3.x-dev",
         "composer/ca-bundle": "^1.2",
         "laminas/laminas-diactoros": "^3.0",
         "laminas/laminas-httphandlerrunner": "^2.6",

+ 2 - 7
phpstan-baseline.neon

@@ -71,11 +71,6 @@ parameters:
 			path: src/Http/Client/Auth/Digest.php
 
 		-
-			message: "#^Call to an undefined method Cake\\\\Chronos\\\\Chronos\\|DateTimeInterface\\:\\:setTimezone\\(\\)\\.$#"
-			count: 2
-			path: src/Http/Cookie/Cookie.php
-
-		-
 			message: "#^Unsafe usage of new static\\(\\)\\.$#"
 			count: 1
 			path: src/Http/Cookie/Cookie.php
@@ -146,11 +141,11 @@ parameters:
 			path: src/View/Form/NullContext.php
 
 		-
-			message: "#^Call to an undefined method Cake\\\\Chronos\\\\Chronos\\|DateTimeInterface\\:\\:setTimezone\\(\\)\\.$#"
+			message: "#^Call to an undefined method DateTimeInterface\\:\\:setTimezone\\(\\)\\.$#"
 			count: 1
 			path: src/View/Helper/TimeHelper.php
 
 		-
-			message: "#^Call to an undefined method Cake\\\\Chronos\\\\Chronos\\|Cake\\\\Chronos\\\\ChronosDate\\|DateTime\\|DateTimeImmutable\\:\\:setTimezone\\(\\)\\.$#"
+			message: "#^Call to an undefined method Cake\\\\Chronos\\\\ChronosDate\\|DateTime\\|DateTimeImmutable\\:\\:setTimezone\\(\\)\\.$#"
 			count: 1
 			path: src/View/Widget/DateTimeWidget.php

+ 1 - 2
src/Database/Expression/CaseExpressionTrait.php

@@ -16,7 +16,6 @@ declare(strict_types=1);
  */
 namespace Cake\Database\Expression;
 
-use Cake\Chronos\Chronos;
 use Cake\Chronos\ChronosDate;
 use Cake\Database\ExpressionInterface;
 use Cake\Database\Query;
@@ -53,7 +52,7 @@ trait CaseExpressionTrait
             $type = 'boolean';
         } elseif ($value instanceof ChronosDate) {
             $type = 'date';
-        } elseif ($value instanceof Chronos || $value instanceof DateTimeInterface) {
+        } elseif ($value instanceof DateTimeInterface) {
             $type = 'datetime';
         } elseif (
             is_object($value) &&

+ 4 - 5
src/Database/Type/DateTimeType.php

@@ -16,7 +16,6 @@ declare(strict_types=1);
  */
 namespace Cake\Database\Type;
 
-use Cake\Chronos\Chronos;
 use Cake\Database\Driver;
 use Cake\Database\Exception\DatabaseException;
 use Cake\I18n\DateTime;
@@ -281,11 +280,11 @@ class DateTimeType extends BaseType implements BatchCastingInterface
      * Convert request data into a datetime object.
      *
      * @param mixed $value Request data
-     * @return \Cake\Chronos\Chronos|\DateTimeInterface|null
+     * @return \DateTimeInterface|null
      */
-    public function marshal(mixed $value): Chronos|DateTimeInterface|null
+    public function marshal(mixed $value): ?DateTimeInterface
     {
-        if ($value instanceof DateTimeInterface || $value instanceof Chronos) {
+        if ($value instanceof DateTimeInterface) {
             if ($value instanceof NativeDateTime) {
                 $value = clone $value;
             }
@@ -439,7 +438,7 @@ class DateTimeType extends BaseType implements BatchCastingInterface
                     return $dateTime;
                 }
             } catch (InvalidArgumentException) {
-                // Chronos wraps DateTime::createFromFormat and throws
+                // Chronos wraps DateTimeImmutable::createFromFormat and throws
                 // exception if parse fails.
                 continue;
             }

+ 20 - 8
src/Http/Cookie/Cookie.php

@@ -15,8 +15,8 @@ declare(strict_types=1);
  */
 namespace Cake\Http\Cookie;
 
-use Cake\Chronos\Chronos;
 use Cake\Utility\Hash;
+use DateTime;
 use DateTimeImmutable;
 use DateTimeInterface;
 use DateTimeZone;
@@ -75,9 +75,9 @@ class Cookie implements CookieInterface
     /**
      * Expiration time
      *
-     * @var \Cake\Chronos\Chronos|\DateTimeInterface|null
+     * @var \DateTimeInterface|null
      */
-    protected Chronos|DateTimeInterface|null $expiresAt = null;
+    protected ?DateTimeInterface $expiresAt = null;
 
     /**
      * Path
@@ -139,7 +139,7 @@ class Cookie implements CookieInterface
      * @link https://php.net/manual/en/function.setcookie.php
      * @param string $name Cookie name
      * @param array|string|float|int|bool $value Value of the cookie
-     * @param \Cake\Chronos\Chronos|\DateTimeInterface|null $expiresAt Expiration time and date
+     * @param \DateTimeInterface|null $expiresAt Expiration time and date
      * @param string|null $path Path
      * @param string|null $domain Domain
      * @param bool|null $secure Is secure
@@ -149,7 +149,7 @@ class Cookie implements CookieInterface
     public function __construct(
         string $name,
         array|string|float|int|bool $value = '',
-        Chronos|DateTimeInterface|null $expiresAt = null,
+        ?DateTimeInterface $expiresAt = null,
         ?string $path = null,
         ?string $domain = null,
         ?bool $secure = null,
@@ -168,6 +168,10 @@ class Cookie implements CookieInterface
         $this->sameSite = static::resolveSameSiteEnum($sameSite ?? static::$defaults['samesite']);
 
         if ($expiresAt) {
+            if ($expiresAt instanceof DateTime) {
+                $expiresAt = clone $expiresAt;
+            }
+            /** @var \DateTimeImmutable|\DateTime $expiresAt */
             $expiresAt = $expiresAt->setTimezone(new DateTimeZone('GMT'));
         } else {
             $expiresAt = static::$defaults['expires'];
@@ -537,8 +541,12 @@ class Cookie implements CookieInterface
     /**
      * @inheritDoc
      */
-    public function withExpiry(Chronos|DateTimeInterface $dateTime): static
+    public function withExpiry(DateTimeInterface $dateTime): static
     {
+        if ($dateTime instanceof DateTime) {
+            $dateTime = clone $dateTime;
+        }
+
         $new = clone $this;
         $new->expiresAt = $dateTime->setTimezone(new DateTimeZone('GMT'));
 
@@ -548,7 +556,7 @@ class Cookie implements CookieInterface
     /**
      * @inheritDoc
      */
-    public function getExpiry(): Chronos|DateTimeInterface|null
+    public function getExpiry(): ?DateTimeInterface
     {
         return $this->expiresAt;
     }
@@ -580,9 +588,13 @@ class Cookie implements CookieInterface
     /**
      * @inheritDoc
      */
-    public function isExpired(Chronos|DateTimeInterface|null $time = null): bool
+    public function isExpired(?DateTimeInterface $time = null): bool
     {
         $time = $time ?: new DateTimeImmutable('now', new DateTimeZone('UTC'));
+        if ($time instanceof DateTime) {
+            $time = clone $time;
+        }
+
         if (!$this->expiresAt) {
             return false;
         }

+ 6 - 7
src/Http/Cookie/CookieInterface.php

@@ -15,7 +15,6 @@ declare(strict_types=1);
  */
 namespace Cake\Http\Cookie;
 
-use Cake\Chronos\Chronos;
 use DateTimeInterface;
 
 /**
@@ -143,9 +142,9 @@ interface CookieInterface
     /**
      * Get the current expiry time
      *
-     * @return \Cake\Chronos\Chronos|\DateTimeInterface|null Timestamp of expiry or null
+     * @return \DateTimeInterface|null Timestamp of expiry or null
      */
-    public function getExpiry(): Chronos|DateTimeInterface|null;
+    public function getExpiry(): ?DateTimeInterface;
 
     /**
      * Get the timestamp from the expiration time
@@ -164,10 +163,10 @@ interface CookieInterface
     /**
      * Create a cookie with an updated expiration date
      *
-     * @param \Cake\Chronos\Chronos|\DateTimeInterface $dateTime Date time object
+     * @param \DateTimeInterface $dateTime Date time object
      * @return static
      */
-    public function withExpiry(Chronos|DateTimeInterface $dateTime): static;
+    public function withExpiry(DateTimeInterface $dateTime): static;
 
     /**
      * Create a new cookie that will virtually never expire.
@@ -190,10 +189,10 @@ interface CookieInterface
      *
      * Cookies without an expiration date always return false.
      *
-     * @param \Cake\Chronos\Chronos|\DateTimeInterface|null $time The time to test against. Defaults to 'now' in UTC.
+     * @param \DateTimeInterface|null $time The time to test against. Defaults to 'now' in UTC.
      * @return bool
      */
-    public function isExpired(Chronos|DateTimeInterface|null $time = null): bool;
+    public function isExpired(?DateTimeInterface $time = null): bool;
 
     /**
      * Check if the cookie is HTTP only

+ 1 - 1
src/I18n/DateTime.php

@@ -444,7 +444,7 @@ class DateTime extends Chronos implements JsonSerializable, Stringable
         $format = is_int($format) ? [$format, $format] : $format;
         $locale = $locale ?: DateTime::getDefaultLocale();
 
-        return $this->_formatObject($time->native, $format, $locale);
+        return $this->_formatObject($time, $format, $locale);
     }
 
     /**

+ 11 - 7
src/I18n/RelativeTimeFormatter.php

@@ -16,7 +16,6 @@ declare(strict_types=1);
  */
 namespace Cake\I18n;
 
-use Cake\Chronos\Chronos;
 use Cake\Chronos\ChronosDate;
 use Cake\Chronos\DifferenceFormatterInterface;
 use DateTimeInterface;
@@ -31,25 +30,30 @@ class RelativeTimeFormatter implements DifferenceFormatterInterface
     /**
      * Get the difference in a human readable format.
      *
-     * @param \Cake\Chronos\Chronos|\Cake\Chronos\ChronosDate $first The datetime to start with.
-     * @param \Cake\Chronos\Chronos|\Cake\Chronos\ChronosDate|\DateTimeInterface|null $second The datetime to compare against.
+     * @param \Cake\Chronos\ChronosDate|\DateTimeInterface $first The datetime to start with.
+     * @param \Cake\Chronos\ChronosDate|\DateTimeInterface|null $second The datetime to compare against.
      * @param bool $absolute Removes time difference modifiers ago, after, etc.
      * @return string The difference between the two days in a human readable format.
      * @see \Cake\Chronos\Chronos::diffForHumans
      */
     public function diffForHumans(
-        Chronos|ChronosDate $first,
-        Chronos|ChronosDate|DateTimeInterface|null $second = null,
+        ChronosDate|DateTimeInterface $first,
+        ChronosDate|DateTimeInterface|null $second = null,
         bool $absolute = false
     ): string {
         $isNow = $second === null;
         if ($second === null) {
             if ($first instanceof ChronosDate) {
-                $second = $first->now();
+                $second = Date::now();
             } else {
-                $second = $first->now($first->getTimezone());
+                $second = DateTime::now($first->getTimezone());
             }
         }
+        assert(
+            ($first instanceof ChronosDate && $second instanceof ChronosDate) ||
+            ($first instanceof DateTimeInterface && $second instanceof DateTimeInterface)
+        );
+
         $diffInterval = $first->diff($second);
 
         switch (true) {

+ 2 - 3
src/ORM/Behavior/TimestampBehavior.php

@@ -16,7 +16,6 @@ declare(strict_types=1);
  */
 namespace Cake\ORM\Behavior;
 
-use Cake\Chronos\Chronos;
 use Cake\Database\Type\DateTimeType;
 use Cake\Database\TypeFactory;
 use Cake\Datasource\EntityInterface;
@@ -144,11 +143,11 @@ class TimestampBehavior extends Behavior
      * If an explicit date time is passed, the config option `refreshTimestamp` is
      * automatically set to false.
      *
-     * @param \Cake\Chronos\Chronos|\DateTimeInterface|null $ts Timestamp
+     * @param \DateTimeInterface|null $ts Timestamp
      * @param bool $refreshTimestamp If true timestamp is refreshed.
      * @return \Cake\I18n\DateTime
      */
-    public function timestamp(Chronos|DateTimeInterface|null $ts = null, bool $refreshTimestamp = false): DateTime
+    public function timestamp(?DateTimeInterface $ts = null, bool $refreshTimestamp = false): DateTime
     {
         if ($ts) {
             if ($this->_config['refreshTimestamp']) {

+ 4 - 5
src/Validation/Validation.php

@@ -16,7 +16,6 @@ declare(strict_types=1);
  */
 namespace Cake\Validation;
 
-use Cake\Chronos\Chronos;
 use Cake\Chronos\ChronosDate;
 use Cake\Core\Exception\CakeException;
 use Cake\I18n\DateTime;
@@ -448,7 +447,7 @@ class Validation
      */
     public static function date(mixed $check, array|string $format = 'ymd', ?string $regex = null): bool
     {
-        if ($check instanceof DateTimeInterface || $check instanceof ChronosDate || $check instanceof Chronos) {
+        if ($check instanceof ChronosDate || $check instanceof DateTimeInterface) {
             return true;
         }
         if (is_object($check)) {
@@ -526,7 +525,7 @@ class Validation
      */
     public static function datetime(mixed $check, array|string $dateFormat = 'ymd', ?string $regex = null): bool
     {
-        if ($check instanceof DateTimeInterface || $check instanceof Chronos) {
+        if ($check instanceof DateTimeInterface) {
             return true;
         }
         if (is_object($check)) {
@@ -594,7 +593,7 @@ class Validation
      */
     public static function time(mixed $check): bool
     {
-        if ($check instanceof DateTimeInterface || $check instanceof Chronos) {
+        if ($check instanceof DateTimeInterface) {
             return true;
         }
         if (is_array($check)) {
@@ -626,7 +625,7 @@ class Validation
      */
     public static function localizedTime(mixed $check, string $type = 'datetime', string|int|null $format = null): bool
     {
-        if ($check instanceof DateTimeInterface || $check instanceof Chronos) {
+        if ($check instanceof DateTimeInterface) {
             return true;
         }
         if (!is_string($check)) {

+ 45 - 42
src/View/Helper/TimeHelper.php

@@ -16,7 +16,6 @@ declare(strict_types=1);
  */
 namespace Cake\View\Helper;
 
-use Cake\Chronos\Chronos;
 use Cake\Chronos\ChronosDate;
 use Cake\I18n\DateTime;
 use Cake\View\Helper;
@@ -64,14 +63,14 @@ class TimeHelper extends Helper
     }
 
     /**
-     * Returns a UNIX timestamp, given either a UNIX timestamp or a valid strtotime() date string.
+     * Returns a DateTime object, given either a UNIX timestamp or a valid strtotime() date string.
      *
-     * @param \Cake\Chronos\Chronos|\Cake\Chronos\ChronosDate|\DateTimeInterface|string|int $dateString UNIX timestamp, strtotime() valid string or DateTime object
+     * @param \Cake\Chronos\ChronosDate|\DateTimeInterface|string|int $dateString UNIX timestamp, strtotime() valid string or DateTime object
      * @param \DateTimeZone|string|null $timezone User's timezone string or DateTimeZone object
      * @return \Cake\I18n\DateTime
      */
     public function fromString(
-        Chronos|ChronosDate|DateTimeInterface|string|int $dateString,
+        ChronosDate|DateTimeInterface|string|int $dateString,
         DateTimeZone|string|null $timezone = null
     ): DateTime {
         $time = new DateTime($dateString);
@@ -91,7 +90,7 @@ class TimeHelper extends Helper
      * @return string Formatted date string
      */
     public function nice(
-        Chronos|ChronosDate|DateTimeInterface|string|int|null $dateString = null,
+        ChronosDate|DateTimeInterface|string|int|null $dateString = null,
         DateTimeZone|string|null $timezone = null,
         ?string $locale = null
     ): string {
@@ -103,12 +102,12 @@ class TimeHelper extends Helper
     /**
      * Returns true, if the given datetime string is today.
      *
-     * @param \Cake\Chronos\Chronos|\Cake\Chronos\ChronosDate|\DateTimeInterface|string|int $dateString UNIX timestamp, strtotime() valid string or DateTime object
+     * @param \Cake\Chronos\ChronosDate|\DateTimeInterface|string|int $dateString UNIX timestamp, strtotime() valid string or DateTime object
      * @param \DateTimeZone|string|null $timezone User's timezone string or DateTimeZone object
      * @return bool True if the given datetime string is today.
      */
     public function isToday(
-        Chronos|ChronosDate|DateTimeInterface|string|int $dateString,
+        ChronosDate|DateTimeInterface|string|int $dateString,
         DateTimeZone|string|null $timezone = null
     ): bool {
         return (new DateTime($dateString, $timezone))->isToday();
@@ -117,12 +116,12 @@ class TimeHelper extends Helper
     /**
      * Returns true, if the given datetime string is in the future.
      *
-     * @param \Cake\Chronos\Chronos|\Cake\Chronos\ChronosDate|\DateTimeInterface|string|int $dateString UNIX timestamp, strtotime() valid string or DateTime object
+     * @param \Cake\Chronos\ChronosDate|\DateTimeInterface|string|int $dateString UNIX timestamp, strtotime() valid string or DateTime object
      * @param \DateTimeZone|string|null $timezone User's timezone string or DateTimeZone object
      * @return bool True if the given datetime string lies in the future.
      */
     public function isFuture(
-        Chronos|ChronosDate|DateTimeInterface|string|int $dateString,
+        ChronosDate|DateTimeInterface|string|int $dateString,
         DateTimeZone|string|null $timezone = null
     ): bool {
         return (new DateTime($dateString, $timezone))->isFuture();
@@ -131,12 +130,12 @@ class TimeHelper extends Helper
     /**
      * Returns true, if the given datetime string is in the past.
      *
-     * @param \Cake\Chronos\Chronos|\Cake\Chronos\ChronosDate|\DateTimeInterface|string|int $dateString UNIX timestamp, strtotime() valid string or DateTime object
+     * @param \Cake\Chronos\ChronosDate|\DateTimeInterface|string|int $dateString UNIX timestamp, strtotime() valid string or DateTime object
      * @param \DateTimeZone|string|null $timezone User's timezone string or DateTimeZone object
      * @return bool True if the given datetime string lies in the past.
      */
     public function isPast(
-        Chronos|ChronosDate|DateTimeInterface|string|int $dateString,
+        ChronosDate|DateTimeInterface|string|int $dateString,
         DateTimeZone|string|null $timezone = null
     ): bool {
         return (new DateTime($dateString, $timezone))->isPast();
@@ -145,12 +144,12 @@ class TimeHelper extends Helper
     /**
      * Returns true if given datetime string is within this week.
      *
-     * @param \Cake\Chronos\Chronos|\Cake\Chronos\ChronosDate|\DateTimeInterface|string|int $dateString UNIX timestamp, strtotime() valid string or DateTime object
+     * @param \Cake\Chronos\ChronosDate|\DateTimeInterface|string|int $dateString UNIX timestamp, strtotime() valid string or DateTime object
      * @param \DateTimeZone|string|null $timezone User's timezone string or DateTimeZone object
      * @return bool True if datetime string is within current week
      */
     public function isThisWeek(
-        Chronos|ChronosDate|DateTimeInterface|string|int $dateString,
+        ChronosDate|DateTimeInterface|string|int $dateString,
         DateTimeZone|string|null $timezone = null
     ): bool {
         return (new DateTime($dateString, $timezone))->isThisWeek();
@@ -159,12 +158,12 @@ class TimeHelper extends Helper
     /**
      * Returns true if given datetime string is within this month
      *
-     * @param \Cake\Chronos\Chronos|\Cake\Chronos\ChronosDate|\DateTimeInterface|string|int $dateString UNIX timestamp, strtotime() valid string or DateTime object
+     * @param \Cake\Chronos\ChronosDate|\DateTimeInterface|string|int $dateString UNIX timestamp, strtotime() valid string or DateTime object
      * @param \DateTimeZone|string|null $timezone User's timezone string or DateTimeZone object
      * @return bool True if datetime string is within the current month
      */
     public function isThisMonth(
-        Chronos|ChronosDate|DateTimeInterface|string|int $dateString,
+        ChronosDate|DateTimeInterface|string|int $dateString,
         DateTimeZone|string|null $timezone = null
     ): bool {
         return (new DateTime($dateString, $timezone))->isThisMonth();
@@ -173,12 +172,12 @@ class TimeHelper extends Helper
     /**
      * Returns true if given datetime string is within the current year.
      *
-     * @param \Cake\Chronos\Chronos|\Cake\Chronos\ChronosDate|\DateTimeInterface|string|int $dateString UNIX timestamp, strtotime() valid string or DateTime object
+     * @param \Cake\Chronos\ChronosDate|\DateTimeInterface|string|int $dateString UNIX timestamp, strtotime() valid string or DateTime object
      * @param \DateTimeZone|string|null $timezone User's timezone string or DateTimeZone object
      * @return bool True if datetime string is within current year
      */
     public function isThisYear(
-        Chronos|ChronosDate|DateTimeInterface|string|int $dateString,
+        ChronosDate|DateTimeInterface|string|int $dateString,
         DateTimeZone|string|null $timezone = null
     ): bool {
         return (new DateTime($dateString, $timezone))->isThisYear();
@@ -187,12 +186,12 @@ class TimeHelper extends Helper
     /**
      * Returns true if given datetime string was yesterday.
      *
-     * @param \Cake\Chronos\Chronos|\Cake\Chronos\ChronosDate|\DateTimeInterface|string|int $dateString UNIX timestamp, strtotime() valid string or DateTime object
+     * @param \Cake\Chronos\ChronosDate|\DateTimeInterface|string|int $dateString UNIX timestamp, strtotime() valid string or DateTime object
      * @param \DateTimeZone|string|null $timezone User's timezone string or DateTimeZone object
      * @return bool True if datetime string was yesterday
      */
     public function wasYesterday(
-        Chronos|ChronosDate|DateTimeInterface|string|int $dateString,
+        ChronosDate|DateTimeInterface|string|int $dateString,
         DateTimeZone|string|null $timezone = null
     ): bool {
         return (new DateTime($dateString, $timezone))->isYesterday();
@@ -201,12 +200,12 @@ class TimeHelper extends Helper
     /**
      * Returns true if given datetime string is tomorrow.
      *
-     * @param \Cake\Chronos\Chronos|\Cake\Chronos\ChronosDate|\DateTimeInterface|string|int $dateString UNIX timestamp, strtotime() valid string or DateTime object
+     * @param \Cake\Chronos\ChronosDate|\DateTimeInterface|string|int $dateString UNIX timestamp, strtotime() valid string or DateTime object
      * @param \DateTimeZone|string|null $timezone User's timezone string or DateTimeZone object
      * @return bool True if datetime string was yesterday
      */
     public function isTomorrow(
-        Chronos|ChronosDate|DateTimeInterface|string|int $dateString,
+        ChronosDate|DateTimeInterface|string|int $dateString,
         DateTimeZone|string|null $timezone = null
     ): bool {
         return (new DateTime($dateString, $timezone))->isTomorrow();
@@ -215,13 +214,13 @@ class TimeHelper extends Helper
     /**
      * Returns the quarter
      *
-     * @param \Cake\Chronos\Chronos|\Cake\Chronos\ChronosDate|\DateTimeInterface|string|int $dateString UNIX timestamp, strtotime() valid string or DateTime object
+     * @param \Cake\Chronos\ChronosDate|\DateTimeInterface|string|int $dateString UNIX timestamp, strtotime() valid string or DateTime object
      * @param bool $range if true returns a range in Y-m-d format
      * @return array<string>|int 1, 2, 3, or 4 quarter of year or array if $range true
      * @see \Cake\I18n\Time::toQuarter()
      */
     public function toQuarter(
-        Chronos|ChronosDate|DateTimeInterface|string|int $dateString,
+        ChronosDate|DateTimeInterface|string|int $dateString,
         bool $range = false
     ): array|int {
         return (new DateTime($dateString))->toQuarter($range);
@@ -230,13 +229,13 @@ class TimeHelper extends Helper
     /**
      * Returns a UNIX timestamp from a textual datetime description.
      *
-     * @param \Cake\Chronos\Chronos|\Cake\Chronos\ChronosDate|\DateTimeInterface|string|int $dateString UNIX timestamp, strtotime() valid string or DateTime object
+     * @param \Cake\Chronos\ChronosDate|\DateTimeInterface|string|int $dateString UNIX timestamp, strtotime() valid string or DateTime object
      * @param \DateTimeZone|string|null $timezone User's timezone string or DateTimeZone object
      * @return string UNIX timestamp
      * @see \Cake\I18n\Time::toUnix()
      */
     public function toUnix(
-        Chronos|ChronosDate|DateTimeInterface|string|int $dateString,
+        ChronosDate|DateTimeInterface|string|int $dateString,
         DateTimeZone|string|null $timezone = null
     ): string {
         return (new DateTime($dateString, $timezone))->toUnixString();
@@ -245,13 +244,13 @@ class TimeHelper extends Helper
     /**
      * Returns a date formatted for Atom RSS feeds.
      *
-     * @param \Cake\Chronos\Chronos|\Cake\Chronos\ChronosDate|\DateTimeInterface|string|int $dateString UNIX timestamp, strtotime() valid string or DateTime object
+     * @param \Cake\Chronos\ChronosDate|\DateTimeInterface|string|int $dateString UNIX timestamp, strtotime() valid string or DateTime object
      * @param \DateTimeZone|string|null $timezone User's timezone string or DateTimeZone object
      * @return string Formatted date string
      * @see \Cake\I18n\Time::toAtom()
      */
     public function toAtom(
-        Chronos|ChronosDate|DateTimeInterface|string|int $dateString,
+        ChronosDate|DateTimeInterface|string|int $dateString,
         DateTimeZone|string|null $timezone = null
     ): string {
         $timezone = $this->_getTimezone($timezone) ?: date_default_timezone_get();
@@ -262,12 +261,12 @@ class TimeHelper extends Helper
     /**
      * Formats date for RSS feeds
      *
-     * @param \Cake\Chronos\Chronos|\Cake\Chronos\ChronosDate|\DateTimeInterface|string|int $dateString UNIX timestamp, strtotime() valid string or DateTime object
+     * @param \Cake\Chronos\ChronosDate|\DateTimeInterface|string|int $dateString UNIX timestamp, strtotime() valid string or DateTime object
      * @param \DateTimeZone|string|null $timezone User's timezone string or DateTimeZone object
      * @return string Formatted date string
      */
     public function toRss(
-        Chronos|ChronosDate|DateTimeInterface|string|int $dateString,
+        ChronosDate|DateTimeInterface|string|int $dateString,
         DateTimeZone|string|null $timezone = null
     ): string {
         $timezone = $this->_getTimezone($timezone) ?: date_default_timezone_get();
@@ -286,14 +285,14 @@ class TimeHelper extends Helper
      *   - `class` - The class name to use, defaults to `time-ago-in-words`.
      *   - `title` - Defaults to the $dateTime input.
      *
-     * @param \Cake\Chronos\Chronos|\Cake\Chronos\ChronosDate|\DateTimeInterface|string|int $dateTime UNIX timestamp, strtotime() valid
+     * @param \Cake\Chronos\ChronosDate|\DateTimeInterface|string|int $dateTime UNIX timestamp, strtotime() valid
      *   string or DateTime object.
      * @param array<string, mixed> $options Default format if timestamp is used in $dateString
      * @return string Relative time string.
      * @see \Cake\I18n\Time::timeAgoInWords()
      */
     public function timeAgoInWords(
-        Chronos|ChronosDate|DateTimeInterface|string|int $dateTime,
+        ChronosDate|DateTimeInterface|string|int $dateTime,
         array $options = []
     ): string {
         $element = null;
@@ -302,7 +301,11 @@ class TimeHelper extends Helper
             'timezone' => null,
         ];
         $options['timezone'] = $this->_getTimezone($options['timezone']);
-        if ($options['timezone'] && ($dateTime instanceof Chronos || $dateTime instanceof DateTimeInterface)) {
+        if ($options['timezone'] && $dateTime instanceof DateTimeInterface) {
+            if ($dateTime instanceof DateTime) {
+                $dateTime = clone $dateTime;
+            }
+            /** @var \DateTimeImmutable|\DateTime $dateTime */
             $dateTime = $dateTime->setTimezone($options['timezone']);
             unset($options['timezone']);
         }
@@ -341,14 +344,14 @@ class TimeHelper extends Helper
      *
      * @param string $timeInterval the numeric value with space then time type.
      *    Example of valid types: 6 hours, 2 days, 1 minute.
-     * @param \Cake\Chronos\Chronos|\Cake\Chronos\ChronosDate|\DateTimeInterface|string|int $dateString UNIX timestamp, strtotime() valid string or DateTime object
+     * @param \Cake\Chronos\ChronosDate|\DateTimeInterface|string|int $dateString UNIX timestamp, strtotime() valid string or DateTime object
      * @param \DateTimeZone|string|null $timezone User's timezone string or DateTimeZone object
      * @return bool
      * @see \Cake\I18n\Time::wasWithinLast()
      */
     public function wasWithinLast(
         string $timeInterval,
-        Chronos|ChronosDate|DateTimeInterface|string|int $dateString,
+        ChronosDate|DateTimeInterface|string|int $dateString,
         DateTimeZone|string|null $timezone = null
     ): bool {
         return (new DateTime($dateString, $timezone))->wasWithinLast($timeInterval);
@@ -359,14 +362,14 @@ class TimeHelper extends Helper
      *
      * @param string $timeInterval the numeric value with space then time type.
      *    Example of valid types: 6 hours, 2 days, 1 minute.
-     * @param \Cake\Chronos\Chronos|\Cake\Chronos\ChronosDate|\DateTimeInterface|string|int $dateString UNIX timestamp, strtotime() valid string or DateTime object
+     * @param \Cake\Chronos\ChronosDate|\DateTimeInterface|string|int $dateString UNIX timestamp, strtotime() valid string or DateTime object
      * @param \DateTimeZone|string|null $timezone User's timezone string or DateTimeZone object
      * @return bool
      * @see \Cake\I18n\Time::wasWithinLast()
      */
     public function isWithinNext(
         string $timeInterval,
-        Chronos|ChronosDate|DateTimeInterface|string|int $dateString,
+        ChronosDate|DateTimeInterface|string|int $dateString,
         DateTimeZone|string|null $timezone = null
     ): bool {
         return (new DateTime($dateString, $timezone))->isWithinNext($timeInterval);
@@ -375,11 +378,11 @@ class TimeHelper extends Helper
     /**
      * Returns gmt as a UNIX timestamp.
      *
-     * @param \Cake\Chronos\Chronos|\Cake\Chronos\ChronosDate|\DateTimeInterface|string|int|null $string UNIX timestamp, strtotime() valid string or DateTime object
+     * @param \Cake\Chronos\ChronosDate|\DateTimeInterface|string|int|null $string UNIX timestamp, strtotime() valid string or DateTime object
      * @return string UNIX timestamp
      * @see \Cake\I18n\Time::gmt()
      */
-    public function gmt(Chronos|ChronosDate|DateTimeInterface|string|int|null $string = null): string
+    public function gmt(ChronosDate|DateTimeInterface|string|int|null $string = null): string
     {
         return (new DateTime($string))->toUnixString();
     }
@@ -390,7 +393,7 @@ class TimeHelper extends Helper
      *
      * This method is an alias for TimeHelper::i18nFormat().
      *
-     * @param \Cake\Chronos\Chronos|\Cake\Chronos\ChronosDate|\DateTimeInterface|string|int|null $date UNIX timestamp, strtotime() valid string
+     * @param \Cake\Chronos\ChronosDate|\DateTimeInterface|string|int|null $date UNIX timestamp, strtotime() valid string
      *   or DateTime object (or a date format string).
      * @param string|int|null $format date format string (or a UNIX timestamp,
      *   `strtotime()` valid string or DateTime object).
@@ -400,7 +403,7 @@ class TimeHelper extends Helper
      * @see \Cake\I18n\Time::i18nFormat()
      */
     public function format(
-        Chronos|ChronosDate|DateTimeInterface|string|int|null $date,
+        ChronosDate|DateTimeInterface|string|int|null $date,
         string|int|null $format = null,
         string|false $invalid = false,
         DateTimeZone|string|null $timezone = null
@@ -412,7 +415,7 @@ class TimeHelper extends Helper
      * Returns a formatted date string, given either a Datetime instance,
      * UNIX timestamp or a valid strtotime() date string.
      *
-     * @param \Cake\Chronos\Chronos|\Cake\Chronos\ChronosDate|\DateTimeInterface|string|int|null $date UNIX timestamp, strtotime() valid string or DateTime object
+     * @param \Cake\Chronos\ChronosDate|\DateTimeInterface|string|int|null $date UNIX timestamp, strtotime() valid string or DateTime object
      * @param array|string|int|null $format Intl compatible format string.
      * @param string|false $invalid Default value to display on invalid dates
      * @param \DateTimeZone|string|null $timezone User's timezone string or DateTimeZone object
@@ -421,7 +424,7 @@ class TimeHelper extends Helper
      * @see \Cake\I18n\Time::i18nFormat()
      */
     public function i18nFormat(
-        Chronos|ChronosDate|DateTimeInterface|string|int|null $date,
+        ChronosDate|DateTimeInterface|string|int|null $date,
         array|string|int|null $format = null,
         string|false $invalid = false,
         DateTimeZone|string|null $timezone = null

+ 4 - 5
src/View/Widget/DateTimeWidget.php

@@ -16,7 +16,6 @@ declare(strict_types=1);
  */
 namespace Cake\View\Widget;
 
-use Cake\Chronos\Chronos;
 use Cake\Chronos\ChronosDate;
 use Cake\Database\Schema\TableSchemaInterface;
 use Cake\View\Form\ContextInterface;
@@ -177,13 +176,13 @@ class DateTimeWidget extends BasicWidget
     /**
      * Formats the passed date/time value into required string format.
      *
-     * @param \Cake\Chronos\Chronos|\Cake\Chronos\ChronosDate|\DateTimeInterface|string|int|null $value Value to deconstruct.
+     * @param \Cake\Chronos\ChronosDate|\DateTimeInterface|string|int|null $value Value to deconstruct.
      * @param array<string, mixed> $options Options for conversion.
      * @return string
      * @throws \InvalidArgumentException If invalid input type is passed.
      */
     protected function formatDateTime(
-        Chronos|ChronosDate|DateTimeInterface|string|int|null $value,
+        ChronosDate|DateTimeInterface|string|int|null $value,
         array $options
     ): string {
         if ($value === '' || $value === null) {
@@ -191,8 +190,8 @@ class DateTimeWidget extends BasicWidget
         }
 
         try {
-            if ($value instanceof Chronos || $value instanceof ChronosDate || $value instanceof DateTimeInterface) {
-                /** @var \Cake\Chronos\Chronos|\Cake\Chronos\ChronosDate|\DateTime|\DateTimeImmutable $dateTime Expand type for phpstan */
+            if ($value instanceof ChronosDate || $value instanceof DateTimeInterface) {
+                /** @var \Cake\Chronos\ChronosDate|\DateTime|\DateTimeImmutable $dateTime Expand type for phpstan */
                 $dateTime = clone $value;
             } elseif (is_string($value) && !is_numeric($value)) {
                 $dateTime = new DateTime($value);

+ 0 - 2
src/View/Widget/YearWidget.php

@@ -16,7 +16,6 @@ declare(strict_types=1);
  */
 namespace Cake\View\Widget;
 
-use Cake\Chronos\Chronos;
 use Cake\Chronos\ChronosDate;
 use Cake\View\Form\ContextInterface;
 use Cake\View\StringTemplate;
@@ -87,7 +86,6 @@ class YearWidget extends BasicWidget
         $data['max'] = (int)$data['max'];
 
         if (
-            $data['val'] instanceof Chronos ||
             $data['val'] instanceof ChronosDate ||
             $data['val'] instanceof DateTimeInterface
         ) {