From 7b3514a9df5dc42a8296f701376ebd56ceee5da6 Mon Sep 17 00:00:00 2001 From: Corey Taylor Date: Sat, 16 Sep 2023 01:35:29 -0500 Subject: [PATCH] Change only Chronos to extend DateTimeImmutable once again --- psalm-baseline.xml | 13 +- src/Chronos.php | 328 ++++++++++----------- src/ChronosDate.php | 44 +-- src/DifferenceFormatter.php | 4 +- src/DifferenceFormatterInterface.php | 8 +- tests/TestCase/DateTime/ComparisonTest.php | 311 +++++++++---------- tests/TestCase/DateTime/StringsTest.php | 6 - 7 files changed, 350 insertions(+), 364 deletions(-) diff --git a/psalm-baseline.xml b/psalm-baseline.xml index 9a68fd73..48989066 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -1,5 +1,5 @@ - + array_filter @@ -11,12 +11,14 @@ diffForHumans diffFormatter format - getTestNow + format + format + format + format + getTimestamp getTimezone getWeekendDays - hasRelativeKeywords hasTestNow - isTimeExpression now now now @@ -87,6 +89,9 @@ f]]> + + public static function createFromFormat( + diff --git a/src/Chronos.php b/src/Chronos.php index 969802b7..1fce3f76 100644 --- a/src/Chronos.php +++ b/src/Chronos.php @@ -20,6 +20,7 @@ use DateTimeInterface; use DateTimeZone; use InvalidArgumentException; +use ReturnTypeWillChange; /** * An Immutable extension on the native DateTime object. @@ -56,7 +57,7 @@ * @psalm-immutable * @psalm-consistent-constructor */ -class Chronos +class Chronos extends DateTimeImmutable { use FormattingTrait; @@ -222,11 +223,6 @@ class Chronos */ protected static array|false $lastErrors = false; - /** - * @var \DateTimeImmutable - */ - protected DateTimeImmutable $native; - /** * Create a new Chronos instance. * @@ -237,25 +233,13 @@ class Chronos * @param \DateTimeZone|string|null $timezone The timezone for the instance */ public function __construct( - Chronos|ChronosDate|DateTimeInterface|string|int|null $time = 'now', + ChronosDate|DateTimeInterface|string|int|null $time = 'now', DateTimeZone|string|null $timezone = null ) { - $this->native = $this->createNative($time, $timezone); - } - - /** - * Initializes the PHP DateTimeImmutable object. - * - * @param \Cake\Chronos\Chronos|\Cake\Chronos\ChronosDate|\DateTimeInterface|string|int|null $time Fixed or relative time - * @param \DateTimeZone|string|null $timezone The timezone for the instance - * @return \DateTimeImmutable - */ - protected function createNative( - Chronos|ChronosDate|DateTimeInterface|string|int|null $time, - DateTimeZone|string|null $timezone = null - ): DateTimeImmutable { if (is_int($time) || (is_string($time) && ctype_digit($time))) { - return new DateTimeImmutable("@{$time}"); + parent::__construct("@{$time}"); + + return; } if ($timezone !== null) { @@ -263,7 +247,7 @@ protected function createNative( } if (is_object($time)) { - if (!$time instanceof ChronosDate) { + if ($time instanceof DateTimeInterface) { $timezone = $time->getTimezone(); } $time = $time->format('Y-m-d H:i:s.u'); @@ -271,12 +255,16 @@ protected function createNative( $testNow = static::getTestNow(); if ($testNow === null) { - return new DateTimeImmutable($time ?? 'now', $timezone); + parent::__construct($time ?? 'now', $timezone); + + return; } $relative = static::hasRelativeKeywords($time); if ($time && $time !== 'now' && !$relative) { - return new DateTimeImmutable($time, $timezone); + parent::__construct($time, $timezone); + + return; } $testNow = clone $testNow; @@ -289,7 +277,7 @@ protected function createNative( $testNow = $testNow->modify($time ?? 'now'); } - return new DateTimeImmutable($testNow->format('Y-m-d H:i:s.u'), $timezone); + parent::__construct($testNow->format('Y-m-d H:i:s.u'), $timezone); } /** @@ -463,7 +451,7 @@ public static function diffFormatter(?DifferenceFormatterInterface $formatter = */ public static function instance(DateTimeInterface $other): static { - return new static($other->format('Y-m-d H:i:s.u'), $other->getTimezone()); + return new static($other); } /** @@ -658,9 +646,9 @@ public static function createFromFormat( DateTimeZone|string|null $timezone = null ): static { if ($timezone !== null) { - $dateTime = DateTimeImmutable::createFromFormat($format, $time, static::safeCreateDateTimeZone($timezone)); + $dateTime = parent::createFromFormat($format, $time, $timezone ? static::safeCreateDateTimeZone($timezone) : null); } else { - $dateTime = DateTimeImmutable::createFromFormat($format, $time); + $dateTime = parent::createFromFormat($format, $time); } static::$lastErrors = DateTimeImmutable::getLastErrors(); @@ -670,8 +658,6 @@ public static function createFromFormat( throw new InvalidArgumentException($message); } - $dateTime = new static($dateTime->format('Y-m-d H:i:s.u'), $dateTime->getTimezone()); - return $dateTime; } @@ -906,10 +892,7 @@ public function setDateTime( */ public function setDate(int $year, int $month, int $day): static { - $new = clone $this; - $new->native = $new->native->setDate($year, $month, $day); - - return $new; + return parent::setDate($year, $month, $day); } /** @@ -922,10 +905,7 @@ public function setDate(int $year, int $month, int $day): static */ public function setISODate(int $year, int $week, int $dayOfWeek = 1): static { - $new = clone $this; - $new->native = $new->native->setISODate($year, $week, $dayOfWeek); - - return $new; + return parent::setISODate($year, $week, $dayOfWeek); } /** @@ -939,10 +919,7 @@ public function setISODate(int $year, int $week, int $dayOfWeek = 1): static */ public function setTime(int $hours, int $minutes, int $seconds = 0, int $microseconds = 0): static { - $new = clone $this; - $new->native = $new->native->setTime($hours, $minutes, $seconds, $microseconds); - - return $new; + return parent::setTime($hours, $minutes, $seconds, $microseconds); } /** @@ -955,29 +932,24 @@ public function setTime(int $hours, int $minutes, int $seconds = 0, int $microse */ public function modify(string $modifier): static { - $native = $this->native->modify($modifier); - if ($native === false) { + $new = parent::modify($modifier); + if ($new === false) { throw new InvalidArgumentException('Unable to modify date using: ' . $modifier); } - $new = clone $this; - $new->native = $native; - return $new; } /** * Returns the difference between this instance and target. * - * @param \Cake\Chronos\Chronos|\DateTimeInterface $target Target instance + * @param \DateTimeInterface $target Target instance * @param bool $absolute Whether the interval is forced to be positive * @return \DateInterval */ - public function diff(Chronos|DateTimeInterface $target, bool $absolute = false): DateInterval + public function diff(DateTimeInterface $target, bool $absolute = false): DateInterval { - $target = $target instanceof DateTimeInterface ? $target : $target->native; - - return $this->native->diff($target, $absolute); + return parent::diff($target, $absolute); } /** @@ -988,7 +960,7 @@ public function diff(Chronos|DateTimeInterface $target, bool $absolute = false): */ public function format(string $format): string { - return $this->native->format($format); + return parent::format($format); } /** @@ -998,7 +970,7 @@ public function format(string $format): string */ public function getOffset(): int { - return $this->native->getOffset(); + return parent::getOffset(); } /** @@ -1009,10 +981,7 @@ public function getOffset(): int */ public function setTimestamp(int $timestamp): static { - $new = clone $this; - $new->native = $new->native->setTimestamp($timestamp); - - return $new; + return parent::setTimestamp($timestamp); } /** @@ -1022,7 +991,7 @@ public function setTimestamp(int $timestamp): static */ public function getTimestamp(): int { - return $this->native->getTimestamp(); + return parent::getTimestamp(); } /** @@ -1033,10 +1002,7 @@ public function getTimestamp(): int */ public function setTimezone(DateTimeZone|string $value): static { - $new = clone $this; - $new->native = $new->native->setTimezone(static::safeCreateDateTimeZone($value)); - - return $new; + return parent::setTimezone(static::safeCreateDateTimeZone($value)); } /** @@ -1044,12 +1010,10 @@ public function setTimezone(DateTimeZone|string $value): static * * @return \DateTimeZone|null */ + #[ReturnTypeWillChange] public function getTimezone(): ?DateTimeZone { - /** @var \DateTimeZone|false $timezone */ - $timezone = $this->native->getTimezone(); - - return $timezone ?: null; + return parent::getTimezone() ?: null; } /** @@ -1608,9 +1572,9 @@ public function endOfWeek(): static * to indicate the desired dayOfWeek, ex. Chronos::MONDAY. * * @param int|null $dayOfWeek The day of the week to move to. - * @return mixed + * @return static */ - public function next(?int $dayOfWeek = null): mixed + public function next(?int $dayOfWeek = null): static { if ($dayOfWeek === null) { $dayOfWeek = $this->dayOfWeek; @@ -1628,9 +1592,9 @@ public function next(?int $dayOfWeek = null): mixed * to indicate the desired dayOfWeek, ex. Chronos::MONDAY. * * @param int|null $dayOfWeek The day of the week to move to. - * @return mixed + * @return static */ - public function previous(?int $dayOfWeek = null): mixed + public function previous(?int $dayOfWeek = null): static { if ($dayOfWeek === null) { $dayOfWeek = $this->dayOfWeek; @@ -1648,9 +1612,9 @@ public function previous(?int $dayOfWeek = null): mixed * to indicate the desired dayOfWeek, ex. Chronos::MONDAY. * * @param int|null $dayOfWeek The day of the week to move to. - * @return mixed + * @return static */ - public function firstOfMonth(?int $dayOfWeek = null): mixed + public function firstOfMonth(?int $dayOfWeek = null): static { $day = $dayOfWeek === null ? 'day' : static::$days[$dayOfWeek]; @@ -1664,9 +1628,9 @@ public function firstOfMonth(?int $dayOfWeek = null): mixed * to indicate the desired dayOfWeek, ex. Chronos::MONDAY. * * @param int|null $dayOfWeek The day of the week to move to. - * @return mixed + * @return static */ - public function lastOfMonth(?int $dayOfWeek = null): mixed + public function lastOfMonth(?int $dayOfWeek = null): static { $day = $dayOfWeek === null ? 'day' : static::$days[$dayOfWeek]; @@ -1681,9 +1645,9 @@ public function lastOfMonth(?int $dayOfWeek = null): mixed * * @param int $nth The offset to use. * @param int $dayOfWeek The day of the week to move to. - * @return mixed + * @return static|false */ - public function nthOfMonth(int $nth, int $dayOfWeek): mixed + public function nthOfMonth(int $nth, int $dayOfWeek): static|false { $dateTime = $this->firstOfMonth(); $check = $dateTime->format('Y-m'); @@ -1699,9 +1663,9 @@ public function nthOfMonth(int $nth, int $dayOfWeek): mixed * to indicate the desired dayOfWeek, ex. Chronos::MONDAY. * * @param int|null $dayOfWeek The day of the week to move to. - * @return mixed + * @return static */ - public function firstOfQuarter(?int $dayOfWeek = null): mixed + public function firstOfQuarter(?int $dayOfWeek = null): static { return $this ->day(1) @@ -1716,9 +1680,9 @@ public function firstOfQuarter(?int $dayOfWeek = null): mixed * to indicate the desired dayOfWeek, ex. Chronos::MONDAY. * * @param int|null $dayOfWeek The day of the week to move to. - * @return mixed + * @return static */ - public function lastOfQuarter(?int $dayOfWeek = null): mixed + public function lastOfQuarter(?int $dayOfWeek = null): static { return $this ->day(1) @@ -1734,9 +1698,9 @@ public function lastOfQuarter(?int $dayOfWeek = null): mixed * * @param int $nth The offset to use. * @param int $dayOfWeek The day of the week to move to. - * @return mixed + * @return static|false */ - public function nthOfQuarter(int $nth, int $dayOfWeek): mixed + public function nthOfQuarter(int $nth, int $dayOfWeek): static|false { $dateTime = $this->day(1)->month($this->quarter * Chronos::MONTHS_PER_QUARTER); $lastMonth = $dateTime->month; @@ -1753,9 +1717,9 @@ public function nthOfQuarter(int $nth, int $dayOfWeek): mixed * to indicate the desired dayOfWeek, ex. Chronos::MONDAY. * * @param int|null $dayOfWeek The day of the week to move to. - * @return mixed + * @return static */ - public function firstOfYear(?int $dayOfWeek = null): mixed + public function firstOfYear(?int $dayOfWeek = null): static { $day = $dayOfWeek === null ? 'day' : static::$days[$dayOfWeek]; @@ -1769,9 +1733,9 @@ public function firstOfYear(?int $dayOfWeek = null): mixed * to indicate the desired dayOfWeek, ex. Chronos::MONDAY. * * @param int|null $dayOfWeek The day of the week to move to. - * @return mixed + * @return static */ - public function lastOfYear(?int $dayOfWeek = null): mixed + public function lastOfYear(?int $dayOfWeek = null): static { $day = $dayOfWeek === null ? 'day' : static::$days[$dayOfWeek]; @@ -1786,9 +1750,9 @@ public function lastOfYear(?int $dayOfWeek = null): mixed * * @param int $nth The offset to use. * @param int $dayOfWeek The day of the week to move to. - * @return mixed + * @return static|false */ - public function nthOfYear(int $nth, int $dayOfWeek): mixed + public function nthOfYear(int $nth, int $dayOfWeek): static|false { $dateTime = $this->firstOfYear()->modify("+$nth " . static::$days[$dayOfWeek]); @@ -1798,21 +1762,21 @@ public function nthOfYear(int $nth, int $dayOfWeek): mixed /** * Determines if the instance is equal to another * - * @param \Cake\Chronos\Chronos $other The instance to compare with. + * @param \DateTimeInterface $other The instance to compare with. * @return bool */ - public function equals(Chronos $other): bool + public function equals(DateTimeInterface $other): bool { - return $this->native == $other->native; + return $this == $other; } /** * Determines if the instance is not equal to another * - * @param \Cake\Chronos\Chronos $other The instance to compare with. + * @param \DateTimeInterface $other The instance to compare with. * @return bool */ - public function notEquals(Chronos $other): bool + public function notEquals(DateTimeInterface $other): bool { return !$this->equals($other); } @@ -1820,58 +1784,58 @@ public function notEquals(Chronos $other): bool /** * Determines if the instance is greater (after) than another * - * @param \Cake\Chronos\Chronos $other The instance to compare with. + * @param \DateTimeInterface $other The instance to compare with. * @return bool */ - public function greaterThan(Chronos $other): bool + public function greaterThan(DateTimeInterface $other): bool { - return $this->native > $other->native; + return $this > $other; } /** * Determines if the instance is greater (after) than or equal to another * - * @param \Cake\Chronos\Chronos $other The instance to compare with. + * @param \DateTimeInterface $other The instance to compare with. * @return bool */ - public function greaterThanOrEquals(Chronos $other): bool + public function greaterThanOrEquals(DateTimeInterface $other): bool { - return $this->native >= $other->native; + return $this >= $other; } /** * Determines if the instance is less (before) than another * - * @param \Cake\Chronos\Chronos $other The instance to compare with. + * @param \DateTimeInterface $other The instance to compare with. * @return bool */ - public function lessThan(Chronos $other): bool + public function lessThan(DateTimeInterface $other): bool { - return $this->native < $other->native; + return $this < $other; } /** * Determines if the instance is less (before) or equal to another * - * @param \Cake\Chronos\Chronos $other The instance to compare with. + * @param \DateTimeInterface $other The instance to compare with. * @return bool */ - public function lessThanOrEquals(Chronos $other): bool + public function lessThanOrEquals(DateTimeInterface $other): bool { - return $this->native <= $other->native; + return $this <= $other; } /** * Determines if the instance is between two others * - * @param \Cake\Chronos\Chronos $start Start of target range - * @param \Cake\Chronos\Chronos $end End of target range + * @param \DateTimeInterface $start Start of target range + * @param \DateTimeInterface $end End of target range * @param bool $equals Whether to include the beginning and end of range * @return bool */ - public function between(Chronos $start, Chronos $end, bool $equals = true): bool + public function between(DateTimeInterface $start, DateTimeInterface $end, bool $equals = true): bool { - if ($start->greaterThan($end)) { + if ($start > $end) { [$start, $end] = [$end, $start]; } @@ -1885,60 +1849,78 @@ public function between(Chronos $start, Chronos $end, bool $equals = true): bool /** * Get the closest date from the instance. * - * @param \Cake\Chronos\Chronos $first The instance to compare with. - * @param \Cake\Chronos\Chronos $second The instance to compare with. + * @param \DateTimeInterface $first The instance to compare with. + * @param \DateTimeInterface $second The instance to compare with. * @return self */ - public function closest(Chronos $first, Chronos $second): Chronos + public function closest(DateTimeInterface $first, DateTimeInterface $second): Chronos { - return $this->diffInSeconds($first) < $this->diffInSeconds($second) ? $first : $second; + $winner = $this->diffInSeconds($first) < $this->diffInSeconds($second) ? $first : $second; + if ($winner instanceof Chronos) { + return $winner; + } + + return new static($winner); } /** * Get the farthest date from the instance. * - * @param \Cake\Chronos\Chronos $first The instance to compare with. - * @param \Cake\Chronos\Chronos $seocnd The instance to compare with. + * @param \DateTimeInterface $first The instance to compare with. + * @param \DateTimeInterface $seocnd The instance to compare with. * @return self */ - public function farthest(Chronos $first, Chronos $seocnd): Chronos + public function farthest(DateTimeInterface $first, DateTimeInterface $seocnd): Chronos { - return $this->diffInSeconds($first) > $this->diffInSeconds($seocnd) ? $first : $seocnd; + $winner = $this->diffInSeconds($first) > $this->diffInSeconds($seocnd) ? $first : $seocnd; + if ($winner instanceof Chronos) { + return $winner; + } + + return new static($winner); } /** * Get the minimum instance between a given instance (default now) and the current instance. * - * @param \Cake\Chronos\Chronos|null $other The instance to compare with. + * @param \DateTimeInterface|null $other The instance to compare with. * @return self */ - public function min(?Chronos $other = null): Chronos + public function min(?DateTimeInterface $other = null): Chronos { $other = $other ?? static::now($this->tz); + $winner = $this->lessThan($other) ? $this : $other; + if ($winner instanceof Chronos) { + return $winner; + } - return $this->lessThan($other) ? $this : $other; + return new static($winner); } /** * Get the maximum instance between a given instance (default now) and the current instance. * - * @param \Cake\Chronos\Chronos|null $other The instance to compare with. + * @param \DateTimeInterface|null $other The instance to compare with. * @return self */ - public function max(?Chronos $other = null): Chronos + public function max(?DateTimeInterface $other = null): Chronos { $other = $other ?? static::now($this->tz); + $winner = $this->greaterThan($other) ? $this : $other; + if ($winner instanceof Chronos) { + return $winner; + } - return $this->greaterThan($other) ? $this : $other; + return new static($winner); } /** * Modify the current instance to the average of a given instance (default now) and the current instance. * - * @param \Cake\Chronos\Chronos|null $other The instance to compare with. + * @param \DateTimeInterface|null $other The instance to compare with. * @return static */ - public function average(?Chronos $other = null): static + public function average(?DateTimeInterface $other = null): static { $other ??= static::now($this->tz); @@ -2088,21 +2070,25 @@ public function isLeapYear(): bool /** * Checks if the passed in date is the same day as the instance current day. * - * @param \Cake\Chronos\Chronos $other The instance to check against. + * @param \DateTimeInterface $other The instance to check against. * @return bool */ - public function isSameDay(Chronos $other): bool + public function isSameDay(DateTimeInterface $other): bool { + if (!$other instanceof Chronos) { + $other = new static($other); + } + return $this->toDateString() === $other->toDateString(); } /** * Returns whether the passed in date is the same month and year. * - * @param \Cake\Chronos\Chronos $other The instance to check against. + * @param \DateTimeInterface $other The instance to check against. * @return bool */ - public function isSameMonth(Chronos $other): bool + public function isSameMonth(DateTimeInterface $other): bool { return $this->format('Y-m') === $other->format('Y-m'); } @@ -2110,10 +2096,10 @@ public function isSameMonth(Chronos $other): bool /** * Returns whether passed in date is the same year. * - * @param \Cake\Chronos\Chronos $other The instance to check against. + * @param \DateTimeInterface $other The instance to check against. * @return bool */ - public function isSameYear(Chronos $other): bool + public function isSameYear(DateTimeInterface $other): bool { return $this->format('Y') === $other->format('Y'); } @@ -2221,10 +2207,10 @@ public function isThisYear(): bool /** * Check if its the birthday. Compares the date/month values of the two dates. * - * @param \Cake\Chronos\Chronos|null $other The instance to compare with or null to use current day. + * @param \DateTimeInterface|null $other The instance to compare with or null to use current day. * @return bool */ - public function isBirthday(?Chronos $other = null): bool + public function isBirthday(?DateTimeInterface $other = null): bool { $other ??= static::now($this->tz); @@ -2268,14 +2254,14 @@ public function isWithinNext(string|int $timeInterval): bool * * @param \DateInterval $interval An interval to traverse by * @param callable $callback The callback to use for filtering. - * @param \Cake\Chronos\Chronos|null $other The instance to difference from. + * @param \DateTimeInterface|null $other The instance to difference from. * @param bool $absolute Get the absolute of the difference * @return int */ public function diffFiltered( DateInterval $interval, callable $callback, - ?Chronos $other = null, + ?DateTimeInterface $other = null, bool $absolute = true ): int { $start = $this; @@ -2288,7 +2274,7 @@ public function diffFiltered( $inverse = true; } - $period = new DatePeriod($start->native, $interval, $end->native); + $period = new DatePeriod($start, $interval, $end); $vals = array_filter(iterator_to_array($period), function (DateTimeInterface $date) use ($callback) { return $callback(static::instance($date)); }); @@ -2301,11 +2287,11 @@ public function diffFiltered( /** * Get the difference in years * - * @param \Cake\Chronos\Chronos|null $other The instance to difference from. + * @param \DateTimeInterface|null $other The instance to difference from. * @param bool $absolute Get the absolute of the difference * @return int */ - public function diffInYears(?Chronos $other = null, bool $absolute = true): int + public function diffInYears(?DateTimeInterface $other = null, bool $absolute = true): int { $diff = $this->diff($other ?? static::now($this->tz), $absolute); @@ -2315,11 +2301,11 @@ public function diffInYears(?Chronos $other = null, bool $absolute = true): int /** * Get the difference in months * - * @param \Cake\Chronos\Chronos|null $other The instance to difference from. + * @param \DateTimeInterface|null $other The instance to difference from. * @param bool $absolute Get the absolute of the difference * @return int */ - public function diffInMonths(?Chronos $other = null, bool $absolute = true): int + public function diffInMonths(?DateTimeInterface $other = null, bool $absolute = true): int { $diff = $this->diff($other ?? static::now($this->tz), $absolute); $months = $diff->y * Chronos::MONTHS_PER_YEAR + $diff->m; @@ -2335,11 +2321,11 @@ public function diffInMonths(?Chronos $other = null, bool $absolute = true): int * For example, if comparing `2019-06-01 Asia/Tokyo` and `2019-10-01 Asia/Tokyo`, * the result would be 4 months instead of 3 when using normal `DateTime::diff()`. * - * @param \Cake\Chronos\Chronos|null $other The instance to difference from. + * @param \DateTimeInterface|null $other The instance to difference from. * @param bool $absolute Get the absolute of the difference * @return int */ - public function diffInMonthsIgnoreTimezone(?Chronos $other = null, bool $absolute = true): int + public function diffInMonthsIgnoreTimezone(?DateTimeInterface $other = null, bool $absolute = true): int { $utcTz = new DateTimeZone('UTC'); $source = new static($this->format('Y-m-d H:i:s.u'), $utcTz); @@ -2353,11 +2339,11 @@ public function diffInMonthsIgnoreTimezone(?Chronos $other = null, bool $absolut /** * Get the difference in weeks * - * @param \Cake\Chronos\Chronos|null $other The instance to difference from. + * @param \DateTimeInterface|null $other The instance to difference from. * @param bool $absolute Get the absolute of the difference * @return int */ - public function diffInWeeks(?Chronos $other = null, bool $absolute = true): int + public function diffInWeeks(?DateTimeInterface $other = null, bool $absolute = true): int { return (int)($this->diffInDays($other, $absolute) / Chronos::DAYS_PER_WEEK); } @@ -2365,11 +2351,11 @@ public function diffInWeeks(?Chronos $other = null, bool $absolute = true): int /** * Get the difference in days * - * @param \Cake\Chronos\Chronos|null $other The instance to difference from. + * @param \DateTimeInterface|null $other The instance to difference from. * @param bool $absolute Get the absolute of the difference * @return int */ - public function diffInDays(?Chronos $other = null, bool $absolute = true): int + public function diffInDays(?DateTimeInterface $other = null, bool $absolute = true): int { $diff = $this->diff($other ?? static::now($this->tz), $absolute); @@ -2380,13 +2366,13 @@ public function diffInDays(?Chronos $other = null, bool $absolute = true): int * Get the difference in days using a filter callable * * @param callable $callback The callback to use for filtering. - * @param \Cake\Chronos\Chronos|null $other The instance to difference from. + * @param \DateTimeInterface|null $other The instance to difference from. * @param bool $absolute Get the absolute of the difference * @return int */ public function diffInDaysFiltered( callable $callback, - ?Chronos $other = null, + ?DateTimeInterface $other = null, bool $absolute = true ): int { return $this->diffFiltered(new DateInterval('P1D'), $callback, $other, $absolute); @@ -2396,13 +2382,13 @@ public function diffInDaysFiltered( * Get the difference in hours using a filter callable * * @param callable $callback The callback to use for filtering. - * @param \Cake\Chronos\Chronos|null $other The instance to difference from. + * @param \DateTimeInterface|null $other The instance to difference from. * @param bool $absolute Get the absolute of the difference * @return int */ public function diffInHoursFiltered( callable $callback, - ?Chronos $other = null, + ?DateTimeInterface $other = null, bool $absolute = true ): int { return $this->diffFiltered(new DateInterval('PT1H'), $callback, $other, $absolute); @@ -2411,13 +2397,13 @@ public function diffInHoursFiltered( /** * Get the difference in weekdays * - * @param \Cake\Chronos\Chronos|null $other The instance to difference from. + * @param \DateTimeInterface|null $other The instance to difference from. * @param bool $absolute Get the absolute of the difference * @return int */ - public function diffInWeekdays(?Chronos $other = null, bool $absolute = true): int + public function diffInWeekdays(?DateTimeInterface $other = null, bool $absolute = true): int { - return $this->diffInDaysFiltered(function (Chronos|ChronosDate $date) { + return $this->diffInDaysFiltered(function (Chronos $date) { return $date->isWeekday(); }, $other, $absolute); } @@ -2425,13 +2411,13 @@ public function diffInWeekdays(?Chronos $other = null, bool $absolute = true): i /** * Get the difference in weekend days using a filter * - * @param \Cake\Chronos\Chronos|null $other The instance to difference from. + * @param \DateTimeInterface|null $other The instance to difference from. * @param bool $absolute Get the absolute of the difference * @return int */ - public function diffInWeekendDays(?Chronos $other = null, bool $absolute = true): int + public function diffInWeekendDays(?DateTimeInterface $other = null, bool $absolute = true): int { - return $this->diffInDaysFiltered(function (Chronos|ChronosDate $date) { + return $this->diffInDaysFiltered(function (Chronos $date) { return $date->isWeekend(); }, $other, $absolute); } @@ -2439,11 +2425,11 @@ public function diffInWeekendDays(?Chronos $other = null, bool $absolute = true) /** * Get the difference in hours * - * @param \Cake\Chronos\Chronos|null $other The instance to difference from. + * @param \DateTimeInterface|null $other The instance to difference from. * @param bool $absolute Get the absolute of the difference * @return int */ - public function diffInHours(?Chronos $other = null, bool $absolute = true): int + public function diffInHours(?DateTimeInterface $other = null, bool $absolute = true): int { return (int)( $this->diffInSeconds($other, $absolute) @@ -2455,11 +2441,11 @@ public function diffInHours(?Chronos $other = null, bool $absolute = true): int /** * Get the difference in minutes * - * @param \Cake\Chronos\Chronos|null $other The instance to difference from. + * @param \DateTimeInterface|null $other The instance to difference from. * @param bool $absolute Get the absolute of the difference * @return int */ - public function diffInMinutes(?Chronos $other = null, bool $absolute = true): int + public function diffInMinutes(?DateTimeInterface $other = null, bool $absolute = true): int { return (int)($this->diffInSeconds($other, $absolute) / Chronos::SECONDS_PER_MINUTE); } @@ -2467,11 +2453,11 @@ public function diffInMinutes(?Chronos $other = null, bool $absolute = true): in /** * Get the difference in seconds * - * @param \Cake\Chronos\Chronos|null $other The instance to difference from. + * @param \DateTimeInterface|null $other The instance to difference from. * @param bool $absolute Get the absolute of the difference * @return int */ - public function diffInSeconds(?Chronos $other = null, bool $absolute = true): int + public function diffInSeconds(?DateTimeInterface $other = null, bool $absolute = true): int { $other ??= static::now($this->tz); $value = $other->getTimestamp() - $this->getTimestamp(); @@ -2502,10 +2488,10 @@ public function secondsUntilEndOfDay(): int /** * Convenience method for getting the remaining time from a given time. * - * @param \Cake\Chronos\Chronos|\DateTimeInterface $other The date to get the remaining time from. + * @param \DateTimeInterface $other The date to get the remaining time from. * @return \DateInterval|bool The DateInterval object representing the difference between the two dates or FALSE on failure. */ - public static function fromNow(Chronos|DateTimeInterface $other): DateInterval|bool + public static function fromNow(DateTimeInterface $other): DateInterval|bool { $timeNow = new static(); @@ -2540,16 +2526,6 @@ public function diffForHumans(?Chronos $other = null, bool $absolute = false): s return static::diffFormatter()->diffForHumans($this, $other, $absolute); } - /** - * Returns the time as a DateTimeImmutable instance. - * - * @return \DateTimeImmutable - */ - public function toNative(): DateTimeImmutable - { - return $this->native; - } - /** * Get a part of the object * diff --git a/src/ChronosDate.php b/src/ChronosDate.php index 941b5158..168a8b02 100644 --- a/src/ChronosDate.php +++ b/src/ChronosDate.php @@ -808,9 +808,9 @@ public function endOfWeek(): static * to indicate the desired dayOfWeek, ex. Chronos::MONDAY. * * @param int|null $dayOfWeek The day of the week to move to. - * @return mixed + * @return static */ - public function next(?int $dayOfWeek = null): mixed + public function next(?int $dayOfWeek = null): static { if ($dayOfWeek === null) { $dayOfWeek = $this->dayOfWeek; @@ -828,9 +828,9 @@ public function next(?int $dayOfWeek = null): mixed * to indicate the desired dayOfWeek, ex. Chronos::MONDAY. * * @param int|null $dayOfWeek The day of the week to move to. - * @return mixed + * @return static */ - public function previous(?int $dayOfWeek = null): mixed + public function previous(?int $dayOfWeek = null): static { if ($dayOfWeek === null) { $dayOfWeek = $this->dayOfWeek; @@ -848,9 +848,9 @@ public function previous(?int $dayOfWeek = null): mixed * to indicate the desired dayOfWeek, ex. Chronos::MONDAY. * * @param int|null $dayOfWeek The day of the week to move to. - * @return mixed + * @return static */ - public function firstOfMonth(?int $dayOfWeek = null): mixed + public function firstOfMonth(?int $dayOfWeek = null): static { $day = $dayOfWeek === null ? 'day' : static::$days[$dayOfWeek]; @@ -864,9 +864,9 @@ public function firstOfMonth(?int $dayOfWeek = null): mixed * to indicate the desired dayOfWeek, ex. Chronos::MONDAY. * * @param int|null $dayOfWeek The day of the week to move to. - * @return mixed + * @return static */ - public function lastOfMonth(?int $dayOfWeek = null): mixed + public function lastOfMonth(?int $dayOfWeek = null): static { $day = $dayOfWeek === null ? 'day' : static::$days[$dayOfWeek]; @@ -881,9 +881,9 @@ public function lastOfMonth(?int $dayOfWeek = null): mixed * * @param int $nth The offset to use. * @param int $dayOfWeek The day of the week to move to. - * @return mixed + * @return static|false */ - public function nthOfMonth(int $nth, int $dayOfWeek): mixed + public function nthOfMonth(int $nth, int $dayOfWeek): static|false { $dateTime = $this->firstOfMonth(); $check = $dateTime->format('Y-m'); @@ -899,9 +899,9 @@ public function nthOfMonth(int $nth, int $dayOfWeek): mixed * to indicate the desired dayOfWeek, ex. Chronos::MONDAY. * * @param int|null $dayOfWeek The day of the week to move to. - * @return mixed + * @return static */ - public function firstOfQuarter(?int $dayOfWeek = null): mixed + public function firstOfQuarter(?int $dayOfWeek = null): static { return $this ->day(1) @@ -916,9 +916,9 @@ public function firstOfQuarter(?int $dayOfWeek = null): mixed * to indicate the desired dayOfWeek, ex. Chronos::MONDAY. * * @param int|null $dayOfWeek The day of the week to move to. - * @return mixed + * @return static */ - public function lastOfQuarter(?int $dayOfWeek = null): mixed + public function lastOfQuarter(?int $dayOfWeek = null): static { return $this ->day(1) @@ -934,9 +934,9 @@ public function lastOfQuarter(?int $dayOfWeek = null): mixed * * @param int $nth The offset to use. * @param int $dayOfWeek The day of the week to move to. - * @return mixed + * @return static|false */ - public function nthOfQuarter(int $nth, int $dayOfWeek): mixed + public function nthOfQuarter(int $nth, int $dayOfWeek): static|false { $dateTime = $this->day(1)->month($this->quarter * Chronos::MONTHS_PER_QUARTER); $lastMonth = $dateTime->month; @@ -953,9 +953,9 @@ public function nthOfQuarter(int $nth, int $dayOfWeek): mixed * to indicate the desired dayOfWeek, ex. Chronos::MONDAY. * * @param int|null $dayOfWeek The day of the week to move to. - * @return mixed + * @return static */ - public function firstOfYear(?int $dayOfWeek = null): mixed + public function firstOfYear(?int $dayOfWeek = null): static { $day = $dayOfWeek === null ? 'day' : static::$days[$dayOfWeek]; @@ -969,9 +969,9 @@ public function firstOfYear(?int $dayOfWeek = null): mixed * to indicate the desired dayOfWeek, ex. Chronos::MONDAY. * * @param int|null $dayOfWeek The day of the week to move to. - * @return mixed + * @return static */ - public function lastOfYear(?int $dayOfWeek = null): mixed + public function lastOfYear(?int $dayOfWeek = null): static { $day = $dayOfWeek === null ? 'day' : static::$days[$dayOfWeek]; @@ -986,9 +986,9 @@ public function lastOfYear(?int $dayOfWeek = null): mixed * * @param int $nth The offset to use. * @param int $dayOfWeek The day of the week to move to. - * @return mixed + * @return static|false */ - public function nthOfYear(int $nth, int $dayOfWeek): mixed + public function nthOfYear(int $nth, int $dayOfWeek): static|false { $dateTime = $this->firstOfYear()->modify("+$nth " . static::$days[$dayOfWeek]); diff --git a/src/DifferenceFormatter.php b/src/DifferenceFormatter.php index 44a0602c..8b588502 100644 --- a/src/DifferenceFormatter.php +++ b/src/DifferenceFormatter.php @@ -45,8 +45,8 @@ public function __construct(?Translator $translate = null) * @inheritDoc */ public function diffForHumans( - Chronos|ChronosDate $first, - Chronos|ChronosDate|null $second = null, + ChronosDate|Chronos $first, + ChronosDate|Chronos|null $second = null, bool $absolute = false ): string { $isNow = $second === null; diff --git a/src/DifferenceFormatterInterface.php b/src/DifferenceFormatterInterface.php index c10efd85..b3181083 100644 --- a/src/DifferenceFormatterInterface.php +++ b/src/DifferenceFormatterInterface.php @@ -21,14 +21,14 @@ interface 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|null $second The datetime to compare against. + * @param \Cake\Chronos\ChronosDate|\Cake\Chronos\Chronos $first The datetime to start with. + * @param \Cake\Chronos\ChronosDate|\Cake\Chronos\Chronos|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 */ public function diffForHumans( - Chronos|ChronosDate $first, - Chronos|ChronosDate|null $second = null, + ChronosDate|Chronos $first, + ChronosDate|Chronos|null $second = null, bool $absolute = false ): string; } diff --git a/tests/TestCase/DateTime/ComparisonTest.php b/tests/TestCase/DateTime/ComparisonTest.php index f7ff51be..b44bb9ce 100644 --- a/tests/TestCase/DateTime/ComparisonTest.php +++ b/tests/TestCase/DateTime/ComparisonTest.php @@ -17,6 +17,8 @@ use Cake\Chronos\Chronos; use Cake\Chronos\Test\TestCase\TestCase; +use DateTimeImmutable; +use DateTimeZone; class ComparisonTest extends TestCase { @@ -32,195 +34,169 @@ public function testGetSetWeekendDays() Chronos::setWeekendDays($expected); } - public function testEqualToTrue() + public function testEquals() { - $this->assertTrue(Chronos::create(2000, 1, 1, 0, 0, 0)->equals(Chronos::create(2000, 1, 1, 0, 0, 0))); - } + $left = Chronos::create(2000, 1, 1, 0, 0, 0); + $this->assertTrue($left == new Chronos('2000-01-01 00:00:00')); + $this->assertTrue($left->equals(new Chronos('2000-01-01 00:00:00'))); + $this->assertTrue($left->equals(new DateTimeImmutable('2000-01-01 00:00:00'))); - public function testEqualToFalse() - { - $this->assertFalse(Chronos::create(2000, 1, 1, 0, 0, 0)->equals(Chronos::create(2000, 1, 2, 0, 0, 0))); - } + $this->assertFalse($left == new Chronos('2000-01-02 00:00:00')); + $this->assertFalse($left->equals(new Chronos('2000-01-02 00:00:00'))); + $this->assertFalse($left->equals(new DateTimeImmutable('2000-01-02 00:00:00'))); - public function testEqualWithTimezoneTrue() - { - $this->assertTrue(Chronos::create(2000, 1, 1, 12, 0, 0, 0, 'America/Toronto')->equals(Chronos::create( - 2000, - 1, - 1, - 9, - 0, - 0, - 0, - 'America/Vancouver' - ))); - } + $left = Chronos::create(2000, 1, 1, 12, 0, 0, 0, 'America/Toronto'); + $this->assertTrue($left == new Chronos('2000-01-01 9:00:00', 'America/Vancouver')); + $this->assertTrue($left->equals(new Chronos('2000-01-01 9:00:00', 'America/Vancouver'))); + $this->assertTrue($left->equals(new DateTimeImmutable('2000-01-01 9:00:00', new DateTimeZone('America/Vancouver')))); - public function testEqualWithTimezoneFalse() - { - $this->assertFalse(Chronos::createFromDate(2000, 1, 1, 'America/Toronto')->equals(Chronos::createFromDate( - 2000, - 1, - 1, - 'America/Vancouver' - ))); + $this->assertFalse($left == new Chronos('2000-01-01 12:00:00', 'America/Vancouver')); + $this->assertFalse($left->equals(new Chronos('2000-01-01 12:00:00', 'America/Vancouver'))); + $this->assertFalse($left->equals(new DateTimeImmutable('2000-01-01 12:00:00', new DateTimeZone('America/Vancouver')))); } - public function testNotEqualToTrue() + public function testNotEquals() { - $this->assertTrue(Chronos::createFromDate(2000, 1, 1)->notEquals(Chronos::createFromDate(2000, 1, 2))); - } + $left = Chronos::create(2000, 1, 1, 0, 0, 0); + $this->assertTrue($left != new Chronos('2000-01-02 00:00:00')); + $this->assertTrue($left->notEquals(new Chronos('2000-01-02 00:00:00'))); + $this->assertTrue($left->notEquals(new DateTimeImmutable('2000-01-02 00:00:00'))); - public function testNotEqualToFalse() - { - $this->assertFalse(Chronos::create(2000, 1, 1, 0, 0, 0)->notEquals(Chronos::create(2000, 1, 1, 0, 0, 0))); - } + $this->assertFalse($left != new Chronos('2000-01-01 00:00:00')); + $this->assertFalse($left->notEquals(new Chronos('2000-01-01 00:00:00'))); + $this->assertFalse($left->notEquals(new DateTimeImmutable('2000-01-01 00:00:00'))); - public function testNotEqualWithTimezone() - { - $this->assertTrue(Chronos::createFromDate(2000, 1, 1, 'America/Toronto')->notEquals(Chronos::createFromDate( - 2000, - 1, - 1, - 'America/Vancouver' - ))); - } + $left = Chronos::create(2000, 1, 1, 12, 0, 0, 0, 'America/Toronto'); + $this->assertTrue($left != new Chronos('2000-01-01 12:00:00', 'America/Vancouver')); + $this->assertTrue($left->notEquals(new Chronos('2000-01-01 12:00:00', 'America/Vancouver'))); + $this->assertTrue($left->notEquals(new DateTimeImmutable('2000-01-01 12:00:00', new DateTimeZone('America/Vancouver')))); - public function testGreaterThanTrue() - { - $this->assertTrue(Chronos::createFromDate(2000, 1, 1)->greaterThan(Chronos::createFromDate(1999, 12, 31))); + $this->assertFalse($left != new Chronos('2000-01-01 9:00:00', 'America/Vancouver')); + $this->assertFalse($left->notEquals(new Chronos('2000-01-01 9:00:00', 'America/Vancouver'))); + $this->assertFalse($left->notEquals(new DateTimeImmutable('2000-01-01 9:00:00', new DateTimeZone('America/Vancouver')))); } - public function testGreaterThanFalse() + public function testGreaterThan() { - $this->assertFalse(Chronos::createFromDate(2000, 1, 1)->greaterThan(Chronos::createFromDate(2000, 1, 2))); - } + $left = Chronos::create(2000, 1, 2, 0, 0, 0); + $this->assertTrue($left > new Chronos('2000-01-01 00:00:00')); + $this->assertTrue($left->greaterThan(new Chronos('2000-01-01 00:00:00'))); + $this->assertTrue($left->greaterThan(new DateTimeImmutable('2000-01-01 00:00:00'))); - public function testGreaterThanWithTimezoneTrue() - { - $dt1 = Chronos::create(2000, 1, 1, 12, 0, 0, 0, 'America/Toronto'); - $dt2 = Chronos::create(2000, 1, 1, 8, 59, 59, 0, 'America/Vancouver'); - $this->assertTrue($dt1->greaterThan($dt2)); - } + $this->assertFalse($left > new Chronos('2000-01-03 00:00:00')); + $this->assertFalse($left->greaterThan(new Chronos('2000-01-03 00:00:00'))); + $this->assertFalse($left->greaterThan(new DateTimeImmutable('2000-01-03 00:00:00'))); - public function testGreaterThanWithTimezoneFalse() - { - $dt1 = Chronos::create(2000, 1, 1, 12, 0, 0, 0, 'America/Toronto'); - $dt2 = Chronos::create(2000, 1, 1, 9, 0, 1, 0, 'America/Vancouver'); - $this->assertFalse($dt1->greaterThan($dt2)); - $this->assertFalse($dt1->greaterThan($dt2)); - } + $left = Chronos::create(2000, 1, 1, 12, 0, 0, 0, 'America/Toronto'); + $this->assertTrue($left > new Chronos('2000-01-01 08:00:00', 'America/Vancouver')); + $this->assertTrue($left->greaterThan(new Chronos('2000-01-01 08:00:00', 'America/Vancouver'))); + $this->assertTrue($left->greaterThan(new DateTimeImmutable('2000-01-01 08:00:00', new DateTimeZone('America/Vancouver')))); - public function testGreaterThanOrEqualTrue() - { - $this->assertTrue(Chronos::create(2000, 1, 1)->greaterThanOrEquals(Chronos::createFromDate(1999, 12, 31))); + $this->assertFalse($left > new Chronos('2000-01-01 09:00:00', 'America/Vancouver')); + $this->assertFalse($left->greaterThan(new Chronos('2000-01-01 09:00:00', 'America/Vancouver'))); + $this->assertFalse($left->greaterThan(new DateTimeImmutable('2000-01-01 09:00:00', new DateTimeZone('America/Vancouver')))); } - public function testGreaterThanOrEqualTrueEqual() + public function testGreaterThanOrEqual() { - $this->assertTrue(Chronos::create(2000, 1, 1, 0, 0, 0)->greaterThanOrEquals(Chronos::create(2000, 1, 1, 0, 0, 0))); - } + $left = Chronos::create(2000, 1, 2, 0, 0, 0); + $this->assertTrue($left >= new Chronos('2000-01-01 00:00:00')); + $this->assertTrue($left->greaterThanOrEquals(new Chronos('2000-01-01 00:00:00'))); + $this->assertTrue($left->greaterThanOrEquals(new DateTimeImmutable('2000-01-01 00:00:00'))); - public function testGreaterThanOrEqualFalse() - { - $this->assertFalse(Chronos::createFromDate(2000, 1, 1)->greaterThanOrEquals(Chronos::createFromDate(2000, 1, 2))); - } + $this->assertTrue($left >= new Chronos('2000-01-02 00:00:00')); + $this->assertTrue($left->greaterThanOrEquals(new Chronos('2000-01-02 00:00:00'))); + $this->assertTrue($left->greaterThanOrEquals(new DateTimeImmutable('2000-01-02 00:00:00'))); - public function testLessThanTrue() - { - $this->assertTrue(Chronos::createFromDate(2000, 1, 1)->lessThan(Chronos::createFromDate(2000, 1, 2))); - } + $this->assertFalse($left >= new Chronos('2000-01-03 00:00:00')); + $this->assertFalse($left->greaterThanOrEquals(new Chronos('2000-01-03 00:00:00'))); + $this->assertFalse($left->greaterThanOrEquals(new DateTimeImmutable('2000-01-03 00:00:00'))); - public function testLessThanFalse() - { - $this->assertFalse(Chronos::createFromDate(2000, 1, 1)->lessThanOrEquals(Chronos::createFromDate(1999, 12, 31))); - } + $left = Chronos::create(2000, 1, 1, 12, 0, 0, 0, 'America/Toronto'); + $this->assertTrue($left >= new Chronos('2000-01-01 09:00:00', 'America/Vancouver')); + $this->assertTrue($left->greaterThanOrEquals(new Chronos('2000-01-01 09:00:00', 'America/Vancouver'))); + $this->assertTrue($left->greaterThanOrEquals(new DateTimeImmutable('2000-01-01 09:00:00', new DateTimeZone('America/Vancouver')))); - public function testLessThanOrEqualTrue() - { - $this->assertTrue(Chronos::createFromDate(2000, 1, 1)->lessThanOrEquals(Chronos::createFromDate(2000, 1, 2))); - } + $this->assertTrue($left >= new Chronos('2000-01-01 08:00:00', 'America/Vancouver')); + $this->assertTrue($left->greaterThanOrEquals(new Chronos('2000-01-01 08:00:00', 'America/Vancouver'))); + $this->assertTrue($left->greaterThanOrEquals(new DateTimeImmutable('2000-01-01 08:00:00', new DateTimeZone('America/Vancouver')))); - public function testLessThanOrEqualTrueEqual() - { - $this->assertTrue(Chronos::createFromDate(2000, 1, 1)->lessThanOrEquals(Chronos::createFromDate(2000, 1, 1))); + $this->assertFalse($left >= new Chronos('2000-01-01 10:00:00', 'America/Vancouver')); + $this->assertFalse($left->greaterThanOrEquals(new Chronos('2000-01-01 10:00:00', 'America/Vancouver'))); + $this->assertFalse($left->greaterThanOrEquals(new DateTimeImmutable('2000-01-01 10:00:00', new DateTimeZone('America/Vancouver')))); } - public function testLessThanOrEqualFalse() + public function testLessThan() { - $this->assertFalse(Chronos::createFromDate(2000, 1, 1)->lessThanOrEquals(Chronos::createFromDate(1999, 12, 31))); - } + $left = Chronos::create(2000, 1, 1, 0, 0, 0); + $this->assertTrue($left < new Chronos('2000-01-02 00:00:00')); + $this->assertTrue($left->lessThan(new Chronos('2000-01-02 00:00:00'))); + $this->assertTrue($left->lessThan(new DateTimeImmutable('2000-01-02 00:00:00'))); - public function testBetweenEqualTrue() - { - $this->assertTrue(Chronos::createFromDate(2000, 1, 15)->between( - Chronos::createFromDate(2000, 1, 1), - Chronos::createFromDate(2000, 1, 31), - true - )); - } + $this->assertFalse($left < new Chronos('2000-01-01 00:00:00')); + $this->assertFalse($left->lessThan(new Chronos('2000-01-01 00:00:00'))); + $this->assertFalse($left->lessThan(new DateTimeImmutable('2000-01-01 00:00:00'))); - public function testBetweenNotEqualTrue() - { - $this->assertTrue(Chronos::createFromDate(2000, 1, 15)->between( - Chronos::createFromDate(2000, 1, 1), - Chronos::createFromDate(2000, 1, 31), - false - )); - } + $left = Chronos::create(2000, 1, 1, 12, 0, 0, 0, 'America/Toronto'); + $this->assertTrue($left < new Chronos('2000-01-01 12:00:00', 'America/Vancouver')); + $this->assertTrue($left->lessThan(new Chronos('2000-01-01 12:00:00', 'America/Vancouver'))); + $this->assertTrue($left->lessThan(new DateTimeImmutable('2000-01-01 12:00:00', new DateTimeZone('America/Vancouver')))); - public function testBetweenEqualFalse() - { - $this->assertFalse(Chronos::createFromDate(1999, 12, 31)->between( - Chronos::createFromDate(2000, 1, 1), - Chronos::createFromDate(2000, 1, 31), - true - )); + $this->assertFalse($left < new Chronos('2000-01-01 09:00:00', 'America/Vancouver')); + $this->assertFalse($left->lessThan(new Chronos('2000-01-01 09:00:00', 'America/Vancouver'))); + $this->assertFalse($left->lessThan(new DateTimeImmutable('2000-01-01 09:00:00', new DateTimeZone('America/Vancouver')))); } - public function testBetweenNotEqualFalse() + public function testLessThanOrEqual() { - $this->assertFalse(Chronos::createFromDate(2000, 1, 1)->between( - Chronos::createFromDate(2000, 1, 1), - Chronos::createFromDate(2000, 1, 31), - false - )); - } + $left = Chronos::create(2000, 1, 2, 0, 0, 0); + $this->assertTrue($left <= new Chronos('2000-01-03 00:00:00')); + $this->assertTrue($left->lessThanOrEquals(new Chronos('2000-01-03 00:00:00'))); + $this->assertTrue($left->lessThanOrEquals(new DateTimeImmutable('2000-01-03 00:00:00'))); - public function testBetweenEqualSwitchTrue() - { - $this->assertTrue(Chronos::createFromDate(2000, 1, 15)->between( - Chronos::createFromDate(2000, 1, 31), - Chronos::createFromDate(2000, 1, 1), - true - )); - } + $this->assertTrue($left <= new Chronos('2000-01-02 00:00:00')); + $this->assertTrue($left->lessThanOrEquals(new Chronos('2000-01-02 00:00:00'))); + $this->assertTrue($left->lessThanOrEquals(new DateTimeImmutable('2000-01-02 00:00:00'))); - public function testBetweenNotEqualSwitchTrue() - { - $this->assertTrue(Chronos::createFromDate(2000, 1, 15)->between( - Chronos::createFromDate(2000, 1, 31), - Chronos::createFromDate(2000, 1, 1), - false - )); - } + $this->assertFalse($left <= new Chronos('2000-01-01 00:00:00')); + $this->assertFalse($left->lessThanOrEquals(new Chronos('2000-01-01 00:00:00'))); + $this->assertFalse($left->lessThanOrEquals(new DateTimeImmutable('2000-01-01 00:00:00'))); - public function testBetweenEqualSwitchFalse() - { - $this->assertFalse(Chronos::createFromDate(1999, 12, 31)->between( - Chronos::createFromDate(2000, 1, 31), - Chronos::createFromDate(2000, 1, 1), - true - )); + $left = Chronos::create(2000, 1, 1, 12, 0, 0, 0, 'America/Toronto'); + $this->assertTrue($left <= new Chronos('2000-01-01 10:00:00', 'America/Vancouver')); + $this->assertTrue($left->lessThanOrEquals(new Chronos('2000-01-01 10:00:00', 'America/Vancouver'))); + $this->assertTrue($left->lessThanOrEquals(new DateTimeImmutable('2000-01-01 10:00:00', new DateTimeZone('America/Vancouver')))); + + $this->assertTrue($left <= new Chronos('2000-01-01 09:00:00', 'America/Vancouver')); + $this->assertTrue($left->lessThanOrEquals(new Chronos('2000-01-01 09:00:00', 'America/Vancouver'))); + $this->assertTrue($left->lessThanOrEquals(new DateTimeImmutable('2000-01-01 09:00:00', new DateTimeZone('America/Vancouver')))); + + $this->assertFalse($left <= new Chronos('2000-01-01 08:00:00', 'America/Vancouver')); + $this->assertFalse($left->lessThanOrEquals(new Chronos('2000-01-01 08:00:00', 'America/Vancouver'))); + $this->assertFalse($left->lessThanOrEquals(new DateTimeImmutable('2000-01-01 08:00:00', new DateTimeZone('America/Vancouver')))); } - public function testBetweenNotEqualSwitchFalse() + public function testBetween() { - $this->assertFalse(Chronos::createFromDate(2000, 1, 1)->between( - Chronos::createFromDate(2000, 1, 31), - Chronos::createFromDate(2000, 1, 1), - false - )); + $date = new Chronos('2000-01-15 00:00:00'); + $this->assertTrue($date->between(new Chronos('2000-01-14 00:00:00'), new Chronos('2000-01-15 00:00:00'))); + $this->assertTrue($date->between(new DateTimeImmutable('2000-01-14 00:00:00'), new DateTimeImmutable('2000-01-15 00:00:00'))); + + $this->assertTrue($date->between(new Chronos('2000-01-14 00:00:00'), new Chronos('2000-01-16 00:00:00'), false)); + $this->assertTrue($date->between(new DateTimeImmutable('2000-01-14 00:00:00'), new DateTimeImmutable('2000-01-16 00:00:00'), false)); + + $this->assertFalse($date->between(new Chronos('2000-01-16 00:00:00'), new Chronos('2000-01-17 00:00:00'))); + $this->assertFalse($date->between(new DateTimeImmutable('2000-01-16 00:00:00'), new DateTimeImmutable('2000-01-17 00:00:00'))); + + $this->assertFalse($date->between(new Chronos('2000-01-14 00:00:00'), new Chronos('2000-01-15 00:00:00'), false)); + $this->assertFalse($date->between(new DateTimeImmutable('2000-01-14 00:00:00'), new DateTimeImmutable('2000-01-15 00:00:00'), false)); + + // switched + $this->assertTrue($date->between(new Chronos('2000-01-16 00:00:00'), new Chronos('2000-01-14 00:00:00'), false)); + $this->assertTrue($date->between(new DateTimeImmutable('2000-01-16 00:00:00'), new DateTimeImmutable('2000-01-14 00:00:00'), false)); + + $this->assertFalse($date->between(new Chronos('2000-01-15 00:00:00'), new Chronos('2000-01-14 00:00:00'), false)); + $this->assertFalse($date->between(new DateTimeImmutable('2000-01-15 00:00:00'), new DateTimeImmutable('2000-01-14 00:00:00'), false)); } public function testMinIsFluid() @@ -240,6 +216,10 @@ public function testMinWithInstance() $dt1 = Chronos::create(2013, 12, 31, 23, 59, 59); $dt2 = Chronos::create(2012, 1, 1, 0, 0, 0)->min($dt1); $this->assertDateTime($dt2, 2012, 1, 1, 0, 0, 0); + + $dt1 = new DateTimeImmutable('2013-12-31 23:59:59'); + $dt2 = Chronos::create(2012, 1, 1, 0, 0, 0)->min($dt1); + $this->assertDateTime($dt2, 2012, 1, 1, 0, 0, 0); } public function testMaxIsFluid() @@ -259,6 +239,10 @@ public function testMaxWithInstance() $dt1 = Chronos::create(2012, 1, 1, 0, 0, 0); $dt2 = Chronos::create(2099, 12, 31, 23, 59, 59)->max($dt1); $this->assertDateTime($dt2, 2099, 12, 31, 23, 59, 59); + + $dt1 = new DateTimeImmutable('2012-01-01 00:00:00'); + $dt2 = Chronos::create(2099, 12, 31, 23, 59, 59)->max($dt1); + $this->assertDateTime($dt2, 2099, 12, 31, 23, 59, 59); } public function testIsBirthday() @@ -276,6 +260,9 @@ public function testIsBirthday() $dt3 = Chronos::createFromDate(2014, 4, 23); $this->assertFalse($dt2->isBirthday($dt1)); $this->assertTrue($dt3->isBirthday($dt1)); + + $this->assertTrue($dt1->isBirthday(new DateTimeImmutable('2014-04-23 00:00:00'))); + $this->assertFalse($dt1->isBirthday(new DateTimeImmutable('2014-04-22 00:00:00'))); } public function testClosest() @@ -285,6 +272,12 @@ public function testClosest() $dt2 = Chronos::create(2015, 5, 28, 14, 0, 0); $closest = $instance->closest($dt1, $dt2); $this->assertSame($dt1, $closest); + + $dt1 = new DateTimeImmutable('2015-05-28 11:00:00'); + $dt2 = new DateTimeImmutable('2015-05-28 14:00:00'); + $closest = $instance->closest($dt1, $dt2); + $this->assertEquals($dt1, $closest); + $this->assertInstanceOf(Chronos::class, $closest); } public function testClosestWithEquals() @@ -294,6 +287,12 @@ public function testClosestWithEquals() $dt2 = Chronos::create(2015, 5, 28, 14, 0, 0); $closest = $instance->closest($dt1, $dt2); $this->assertSame($dt1, $closest); + + $dt1 = new DateTimeImmutable('2015-05-28 11:00:00'); + $dt2 = new DateTimeImmutable('2015-05-28 14:00:00'); + $closest = $instance->closest($dt1, $dt2); + $this->assertEquals($dt1, $closest); + $this->assertInstanceOf(Chronos::class, $closest); } public function testFarthest() @@ -303,6 +302,12 @@ public function testFarthest() $dt2 = Chronos::create(2015, 5, 28, 14, 0, 0); $Farthest = $instance->farthest($dt1, $dt2); $this->assertSame($dt2, $Farthest); + + $dt1 = new DateTimeImmutable('2015-05-28 11:00:00'); + $dt2 = new DateTimeImmutable('2015-05-28 14:00:00'); + $farthest = $instance->farthest($dt1, $dt2); + $this->assertEquals($dt2, $farthest); + $this->assertInstanceOf(Chronos::class, $farthest); } public function testFarthestWithEquals() @@ -312,5 +317,11 @@ public function testFarthestWithEquals() $dt2 = Chronos::create(2015, 5, 28, 14, 0, 0); $Farthest = $instance->farthest($dt1, $dt2); $this->assertSame($dt2, $Farthest); + + $dt1 = new DateTimeImmutable('2015-05-28 12:00:00'); + $dt2 = new DateTimeImmutable('2015-05-28 14:00:00'); + $farthest = $instance->farthest($dt1, $dt2); + $this->assertEquals($dt2, $farthest); + $this->assertInstanceOf(Chronos::class, $farthest); } } diff --git a/tests/TestCase/DateTime/StringsTest.php b/tests/TestCase/DateTime/StringsTest.php index 716e839c..37eb170e 100644 --- a/tests/TestCase/DateTime/StringsTest.php +++ b/tests/TestCase/DateTime/StringsTest.php @@ -213,10 +213,4 @@ public function testToWeek($date, $expected) { $this->assertSame($expected, (new Chronos($date))->toWeek()); } - - public function testToNative(): void - { - $c = Chronos::now(); - $this->assertSame($c->format(DATE_ATOM), $c->toNative()->format(DATE_ATOM)); - } }