From e0d4eaf723bb34f6e01a0a0573942a4f68a96036 Mon Sep 17 00:00:00 2001 From: mscherer Date: Mon, 23 Mar 2026 00:07:55 +0100 Subject: [PATCH 1/2] Improve documentation coverage - Expand README with ChronosTime, setTestNow, and ClockFactory examples - Improve ClockFactory class and method documentation - Add detailed docs for createInterval() explaining rollover behavior - Improve average() docs with example showing midpoint calculation - Improve diffFiltered() docs with callback signature and example - Improve nthOfMonth/Quarter/Year docs explaining false return case --- README.md | 58 ++++++++++++++++++++ src/Chronos.php | 123 +++++++++++++++++++++++++++++++++---------- src/ChronosDate.php | 92 ++++++++++++++++++++++---------- src/ClockFactory.php | 17 +++++- 4 files changed, 232 insertions(+), 58 deletions(-) diff --git a/README.md b/README.md index 3fe1e99a..8c16110d 100644 --- a/README.md +++ b/README.md @@ -77,6 +77,64 @@ echo $today->modify('+3 hours'); Like instances of `Chronos`, `ChronosDate` objects are also *immutable*. +# Time-only Values + +When you need to work with just times (without dates), use `ChronosTime`: + +```php +use Cake\Chronos\ChronosTime; + +$time = new ChronosTime('14:30:00'); +echo $time->format('g:i A'); // 2:30 PM + +// Create from components +$time = ChronosTime::create(14, 30, 0); + +// Arithmetic +$later = $time->addHours(2)->addMinutes(15); +``` + +`ChronosTime` is useful for recurring schedules, business hours, or any scenario +where the date is irrelevant. + +# Testing with Chronos + +Chronos provides `setTestNow()` to freeze time during testing: + +```php +use Cake\Chronos\Chronos; + +// Freeze time for predictable tests +Chronos::setTestNow('2024-01-15 10:00:00'); + +$now = Chronos::now(); // Always 2024-01-15 10:00:00 + +// Reset to real time +Chronos::setTestNow(null); +``` + +# PSR-20 Clock Interface + +For dependency injection, use `ClockFactory` which implements PSR-20: + +```php +use Cake\Chronos\ClockFactory; + +$clock = new ClockFactory('UTC'); +$now = $clock->now(); // Returns Chronos instance + +// In your service +class OrderService +{ + public function __construct(private ClockInterface $clock) {} + + public function createOrder(): Order + { + return new Order(createdAt: $this->clock->now()); + } +} +``` + # Documentation A more descriptive documentation can be found at [book.cakephp.org/chronos/3/](https://book.cakephp.org/chronos/3/). diff --git a/src/Chronos.php b/src/Chronos.php index a74bfb65..8bdb8a32 100644 --- a/src/Chronos.php +++ b/src/Chronos.php @@ -769,6 +769,22 @@ protected static function safeCreateDateTimeZone(DateTimeZone|string|null $objec /** * Create a new DateInterval instance from specified values. * + * Values that exceed their natural limits will automatically roll over + * to the next higher unit. For example, 90 minutes becomes 1 hour and + * 30 minutes, 25 hours becomes 1 day and 1 hour. + * + * Rollover cascades upward: microseconds -> seconds -> minutes -> hours -> days. + * Years, months, and weeks do not roll over. + * + * Example: + * ``` + * // 90 seconds becomes 1 minute 30 seconds + * $interval = Chronos::createInterval(seconds: 90); + * + * // 25 hours becomes 1 day 1 hour + * $interval = Chronos::createInterval(hours: 25); + * ``` + * * @param int|null $years The year to use. * @param int|null $months The month to use. * @param int|null $weeks The week to use. @@ -1651,14 +1667,22 @@ public function lastOfMonth(?int $dayOfWeek = null): static } /** - * Modify to the given occurrence of a given day of the week - * in the current month. If the calculated occurrence is outside the scope - * of the current month, then return false and no modifications are made. - * Use the supplied consts to indicate the desired dayOfWeek, ex. Chronos::MONDAY. + * Get the nth occurrence of a day of the week in the current month. * - * @param int $nth The offset to use. - * @param int $dayOfWeek The day of the week to move to. - * @return static|false + * Returns false if the requested occurrence doesn't exist in the month. + * For example, requesting the 5th Monday will return false for months + * that only have 4 Mondays. + * + * Example: + * ``` + * $date = new Chronos('2024-01-15'); + * $date->nthOfMonth(2, Chronos::TUESDAY); // 2nd Tuesday of January + * $date->nthOfMonth(5, Chronos::MONDAY); // false if no 5th Monday + * ``` + * + * @param int $nth The occurrence number (1 = first, 2 = second, etc.). + * @param int $dayOfWeek The day of the week (use Chronos::MONDAY, etc.). + * @return static|false The date of the nth occurrence, or false if it doesn't exist. */ public function nthOfMonth(int $nth, int $dayOfWeek): static|false { @@ -1704,14 +1728,20 @@ public function lastOfQuarter(?int $dayOfWeek = null): static } /** - * Modify to the given occurrence of a given day of the week - * in the current quarter. If the calculated occurrence is outside the scope - * of the current quarter, then return false and no modifications are made. - * Use the supplied consts to indicate the desired dayOfWeek, ex. Chronos::MONDAY. + * Get the nth occurrence of a day of the week in the current quarter. * - * @param int $nth The offset to use. - * @param int $dayOfWeek The day of the week to move to. - * @return static|false + * Returns false if the requested occurrence doesn't exist in the quarter. + * Quarters are: Q1 (Jan-Mar), Q2 (Apr-Jun), Q3 (Jul-Sep), Q4 (Oct-Dec). + * + * Example: + * ``` + * $date = new Chronos('2024-02-15'); // Q1 + * $date->nthOfQuarter(5, Chronos::FRIDAY); // 5th Friday of Q1 + * ``` + * + * @param int $nth The occurrence number (1 = first, 2 = second, etc.). + * @param int $dayOfWeek The day of the week (use Chronos::MONDAY, etc.). + * @return static|false The date of the nth occurrence, or false if it doesn't exist. */ public function nthOfQuarter(int $nth, int $dayOfWeek): static|false { @@ -1756,13 +1786,20 @@ public function lastOfYear(?int $dayOfWeek = null): static } /** - * Modify to the given occurrence of a given day of the week - * in the current year. If the calculated occurrence is outside the scope - * of the current year, then return false and no modifications are made. - * Use the supplied consts to indicate the desired dayOfWeek, ex. Chronos::MONDAY. + * Get the nth occurrence of a day of the week in the current year. + * + * Returns false if the requested occurrence doesn't exist in the year + * (e.g., requesting the 53rd Monday in a year with only 52). * - * @param int $nth The offset to use. - * @param int $dayOfWeek The day of the week to move to. + * Example: + * ``` + * $date = new Chronos('2024-06-15'); + * $date->nthOfYear(1, Chronos::MONDAY); // First Monday of the year + * $date->nthOfYear(52, Chronos::FRIDAY); // 52nd Friday of the year + * ``` + * + * @param int $nth The occurrence number (1 = first, 2 = second, etc.). + * @param int $dayOfWeek The day of the week (use Chronos::MONDAY, etc.). * @return static|false */ public function nthOfYear(int $nth, int $dayOfWeek): static|false @@ -1948,10 +1985,21 @@ public function max(?DateTimeInterface $other = null): static } /** - * Modify the current instance to the average of a given instance (default now) and the current instance. + * Get the midpoint between this instance and another. * - * @param \DateTimeInterface|null $other The instance to compare with. - * @return static + * Calculates the datetime that is exactly halfway between the current + * instance and the given instance. If no other instance is provided, + * uses the current time (now). + * + * Example: + * ``` + * $jan1 = new Chronos('2024-01-01 00:00:00'); + * $jan3 = new Chronos('2024-01-03 00:00:00'); + * $midpoint = $jan1->average($jan3); // 2024-01-02 00:00:00 + * ``` + * + * @param \DateTimeInterface|null $other The instance to find midpoint with. Defaults to now. + * @return static The datetime exactly between this instance and the other. */ public function average(?DateTimeInterface $other = null): static { @@ -2303,14 +2351,31 @@ public function isWithinNext(string|int $timeInterval): bool } /** - * Get the difference by the given interval using a filter callable + * Get the difference by the given interval using a filter callback. * - * @param \DateInterval $interval An interval to traverse by - * @param callable $callback The callback to use for filtering. - * @param \DateTimeInterface|null $other The instance to difference from. - * @param bool $absolute Get the absolute of the difference + * Iterates through the date range at the given interval and counts + * how many times the callback returns true. + * + * Example: + * ``` + * // Count weekdays between two dates + * $start = new Chronos('2024-01-01'); + * $end = new Chronos('2024-01-31'); + * $weekdays = $start->diffFiltered( + * new DateInterval('P1D'), + * fn($date) => !$date->isWeekend(), + * $end + * ); + * ``` + * + * @param \DateInterval $interval An interval to traverse by (e.g., P1D for daily). + * @param callable $callback Filter function that receives each date in the range. + * Should return true to count the date, false to skip it. + * Signature: `function(Chronos $date): bool` + * @param \DateTimeInterface|null $other The end date. Defaults to now. + * @param bool $absolute Get the absolute of the difference. * @param int $options DatePeriod options, {@see https://www.php.net/manual/en/class.dateperiod.php} - * @return int + * @return int The count of intervals where the callback returned true. */ public function diffFiltered( DateInterval $interval, diff --git a/src/ChronosDate.php b/src/ChronosDate.php index 85bad798..24d8d1c8 100644 --- a/src/ChronosDate.php +++ b/src/ChronosDate.php @@ -884,14 +884,22 @@ public function lastOfMonth(?int $dayOfWeek = null): static } /** - * Modify to the given occurrence of a given day of the week - * in the current month. If the calculated occurrence is outside the scope - * of the current month, then return false and no modifications are made. - * Use the supplied consts to indicate the desired dayOfWeek, ex. Chronos::MONDAY. + * Get the nth occurrence of a day of the week in the current month. * - * @param int $nth The offset to use. - * @param int $dayOfWeek The day of the week to move to. - * @return static|false + * Returns false if the requested occurrence doesn't exist in the month. + * For example, requesting the 5th Monday will return false for months + * that only have 4 Mondays. + * + * Example: + * ``` + * $date = new ChronosDate('2024-01-15'); + * $date->nthOfMonth(2, Chronos::TUESDAY); // 2nd Tuesday of January + * $date->nthOfMonth(5, Chronos::MONDAY); // false if no 5th Monday + * ``` + * + * @param int $nth The occurrence number (1 = first, 2 = second, etc.). + * @param int $dayOfWeek The day of the week (use Chronos::MONDAY, etc.). + * @return static|false The date of the nth occurrence, or false if it doesn't exist. */ public function nthOfMonth(int $nth, int $dayOfWeek): static|false { @@ -937,14 +945,20 @@ public function lastOfQuarter(?int $dayOfWeek = null): static } /** - * Modify to the given occurrence of a given day of the week - * in the current quarter. If the calculated occurrence is outside the scope - * of the current quarter, then return false and no modifications are made. - * Use the supplied consts to indicate the desired dayOfWeek, ex. Chronos::MONDAY. + * Get the nth occurrence of a day of the week in the current quarter. + * + * Returns false if the requested occurrence doesn't exist in the quarter. + * Quarters are: Q1 (Jan-Mar), Q2 (Apr-Jun), Q3 (Jul-Sep), Q4 (Oct-Dec). * - * @param int $nth The offset to use. - * @param int $dayOfWeek The day of the week to move to. - * @return static|false + * Example: + * ``` + * $date = new ChronosDate('2024-02-15'); // Q1 + * $date->nthOfQuarter(5, Chronos::FRIDAY); // 5th Friday of Q1 + * ``` + * + * @param int $nth The occurrence number (1 = first, 2 = second, etc.). + * @param int $dayOfWeek The day of the week (use Chronos::MONDAY, etc.). + * @return static|false The date of the nth occurrence, or false if it doesn't exist. */ public function nthOfQuarter(int $nth, int $dayOfWeek): static|false { @@ -989,14 +1003,21 @@ public function lastOfYear(?int $dayOfWeek = null): static } /** - * Modify to the given occurrence of a given day of the week - * in the current year. If the calculated occurrence is outside the scope - * of the current year, then return false and no modifications are made. - * Use the supplied consts to indicate the desired dayOfWeek, ex. Chronos::MONDAY. + * Get the nth occurrence of a day of the week in the current year. + * + * Returns false if the requested occurrence doesn't exist in the year + * (e.g., requesting the 53rd Monday in a year with only 52). + * + * Example: + * ``` + * $date = new ChronosDate('2024-06-15'); + * $date->nthOfYear(1, Chronos::MONDAY); // First Monday of the year + * $date->nthOfYear(52, Chronos::FRIDAY); // 52nd Friday of the year + * ``` * - * @param int $nth The offset to use. - * @param int $dayOfWeek The day of the week to move to. - * @return static|false + * @param int $nth The occurrence number (1 = first, 2 = second, etc.). + * @param int $dayOfWeek The day of the week (use Chronos::MONDAY, etc.). + * @return static|false The date of the nth occurrence, or false if it doesn't exist. */ public function nthOfYear(int $nth, int $dayOfWeek): static|false { @@ -1412,14 +1433,31 @@ public function isWithinNext(string|int $timeInterval): bool } /** - * Get the difference by the given interval using a filter callable + * Get the difference by the given interval using a filter callback. * - * @param \DateInterval $interval An interval to traverse by - * @param callable $callback The callback to use for filtering. - * @param \Cake\Chronos\ChronosDate|null $other The instance to difference from. - * @param bool $absolute Get the absolute of the difference + * Iterates through the date range at the given interval and counts + * how many times the callback returns true. + * + * Example: + * ``` + * // Count weekdays between two dates + * $start = new ChronosDate('2024-01-01'); + * $end = new ChronosDate('2024-01-31'); + * $weekdays = $start->diffFiltered( + * new DateInterval('P1D'), + * fn($date) => !$date->isWeekend(), + * $end + * ); + * ``` + * + * @param \DateInterval $interval An interval to traverse by (e.g., P1D for daily). + * @param callable $callback Filter function that receives each date in the range. + * Should return true to count the date, false to skip it. + * Signature: `function(ChronosDate $date): bool` + * @param \Cake\Chronos\ChronosDate|null $other The end date. Defaults to today. + * @param bool $absolute Get the absolute of the difference. * @param int $options DatePeriod options, {@see https://www.php.net/manual/en/class.dateperiod.php} - * @return int + * @return int The count of intervals where the callback returned true. */ public function diffFiltered( DateInterval $interval, diff --git a/src/ClockFactory.php b/src/ClockFactory.php index a5dbc176..402eb580 100644 --- a/src/ClockFactory.php +++ b/src/ClockFactory.php @@ -20,6 +20,16 @@ /** * PSR-20 Clock implementation. + * + * Provides a PSR-20 compatible clock that returns Chronos instances. + * Useful for dependency injection and testing scenarios where you need + * to control the current time. + * + * Example: + * ``` + * $clock = new ClockFactory('UTC'); + * $now = $clock->now(); // Returns Chronos instance + * ``` */ class ClockFactory implements ClockInterface { @@ -36,9 +46,12 @@ public function __construct(DateTimeZone|string|null $timezone = null) } /** - * Returns the current time object. + * Returns the current time as a Chronos instance. + * + * The return type is DateTimeImmutable for PSR-20 compatibility, + * but the actual returned instance is always Chronos. * - * @return \Cake\Chronos\Chronos The current time + * @return \Cake\Chronos\Chronos */ public function now(): DateTimeImmutable { From c26894ad15a00d068c9c63a92f0476caf9b2b816 Mon Sep 17 00:00:00 2001 From: mscherer Date: Mon, 23 Mar 2026 00:12:45 +0100 Subject: [PATCH 2/2] Improve firstOf*/lastOf* and min/max documentation - Clarify @param for $dayOfWeek to specify Chronos constants - Improve min() docs explaining it returns the earlier datetime - Improve max() docs explaining it returns the later datetime - Document that null defaults to current time for min/max --- src/Chronos.php | 42 ++++++++++++++++++++++++++++-------------- src/ChronosDate.php | 24 ++++++++++++++++-------- 2 files changed, 44 insertions(+), 22 deletions(-) diff --git a/src/Chronos.php b/src/Chronos.php index 8bdb8a32..cc5626c1 100644 --- a/src/Chronos.php +++ b/src/Chronos.php @@ -1600,7 +1600,8 @@ public function endOfWeek(): static * of the current day of the week. Use the supplied consts * to indicate the desired dayOfWeek, ex. Chronos::MONDAY. * - * @param int|null $dayOfWeek The day of the week to move to. + * @param int|null $dayOfWeek The day of the week (use Chronos::MONDAY through + * Chronos::SUNDAY), or null for a sensible default. * @return static */ public function next(?int $dayOfWeek = null): static @@ -1620,7 +1621,8 @@ public function next(?int $dayOfWeek = null): static * of the current day of the week. Use the supplied consts * to indicate the desired dayOfWeek, ex. Chronos::MONDAY. * - * @param int|null $dayOfWeek The day of the week to move to. + * @param int|null $dayOfWeek The day of the week (use Chronos::MONDAY through + * Chronos::SUNDAY), or null for a sensible default. * @return static */ public function previous(?int $dayOfWeek = null): static @@ -1640,7 +1642,8 @@ public function previous(?int $dayOfWeek = null): static * first day of the current month. Use the supplied consts * to indicate the desired dayOfWeek, ex. Chronos::MONDAY. * - * @param int|null $dayOfWeek The day of the week to move to. + * @param int|null $dayOfWeek The day of the week (use Chronos::MONDAY through + * Chronos::SUNDAY), or null for a sensible default. * @return static */ public function firstOfMonth(?int $dayOfWeek = null): static @@ -1656,7 +1659,8 @@ public function firstOfMonth(?int $dayOfWeek = null): static * last day of the current month. Use the supplied consts * to indicate the desired dayOfWeek, ex. Chronos::MONDAY. * - * @param int|null $dayOfWeek The day of the week to move to. + * @param int|null $dayOfWeek The day of the week (use Chronos::MONDAY through + * Chronos::SUNDAY), or null for a sensible default. * @return static */ public function lastOfMonth(?int $dayOfWeek = null): static @@ -1699,7 +1703,8 @@ public function nthOfMonth(int $nth, int $dayOfWeek): static|false * first day of the current quarter. Use the supplied consts * to indicate the desired dayOfWeek, ex. Chronos::MONDAY. * - * @param int|null $dayOfWeek The day of the week to move to. + * @param int|null $dayOfWeek The day of the week (use Chronos::MONDAY through + * Chronos::SUNDAY), or null for a sensible default. * @return static */ public function firstOfQuarter(?int $dayOfWeek = null): static @@ -1716,7 +1721,8 @@ public function firstOfQuarter(?int $dayOfWeek = null): static * last day of the current quarter. Use the supplied consts * to indicate the desired dayOfWeek, ex. Chronos::MONDAY. * - * @param int|null $dayOfWeek The day of the week to move to. + * @param int|null $dayOfWeek The day of the week (use Chronos::MONDAY through + * Chronos::SUNDAY), or null for a sensible default. * @return static */ public function lastOfQuarter(?int $dayOfWeek = null): static @@ -1759,7 +1765,8 @@ public function nthOfQuarter(int $nth, int $dayOfWeek): static|false * first day of the current year. Use the supplied consts * to indicate the desired dayOfWeek, ex. Chronos::MONDAY. * - * @param int|null $dayOfWeek The day of the week to move to. + * @param int|null $dayOfWeek The day of the week (use Chronos::MONDAY through + * Chronos::SUNDAY), or null for a sensible default. * @return static */ public function firstOfYear(?int $dayOfWeek = null): static @@ -1775,7 +1782,8 @@ public function firstOfYear(?int $dayOfWeek = null): static * last day of the current year. Use the supplied consts * to indicate the desired dayOfWeek, ex. Chronos::MONDAY. * - * @param int|null $dayOfWeek The day of the week to move to. + * @param int|null $dayOfWeek The day of the week (use Chronos::MONDAY through + * Chronos::SUNDAY), or null for a sensible default. * @return static */ public function lastOfYear(?int $dayOfWeek = null): static @@ -1951,10 +1959,13 @@ public function farthest(DateTimeInterface $first, DateTimeInterface $second, Da } /** - * Get the minimum instance between a given instance (default now) and the current instance. + * Get the earlier of this instance and another. * - * @param \DateTimeInterface|null $other The instance to compare with. - * @return static + * Returns whichever datetime comes first chronologically. + * If no other instance is provided, compares against the current time. + * + * @param \DateTimeInterface|null $other The instance to compare with. Defaults to now. + * @return static The earlier of the two datetimes. */ public function min(?DateTimeInterface $other = null): static { @@ -1968,10 +1979,13 @@ public function min(?DateTimeInterface $other = null): static } /** - * Get the maximum instance between a given instance (default now) and the current instance. + * Get the later of this instance and another. * - * @param \DateTimeInterface|null $other The instance to compare with. - * @return static + * Returns whichever datetime comes last chronologically. + * If no other instance is provided, compares against the current time. + * + * @param \DateTimeInterface|null $other The instance to compare with. Defaults to now. + * @return static The later of the two datetimes. */ public function max(?DateTimeInterface $other = null): static { diff --git a/src/ChronosDate.php b/src/ChronosDate.php index 24d8d1c8..147c72fc 100644 --- a/src/ChronosDate.php +++ b/src/ChronosDate.php @@ -817,7 +817,8 @@ public function endOfWeek(): static * of the current day of the week. Use the supplied consts * to indicate the desired dayOfWeek, ex. Chronos::MONDAY. * - * @param int|null $dayOfWeek The day of the week to move to. + * @param int|null $dayOfWeek The day of the week (use Chronos::MONDAY through + * Chronos::SUNDAY), or null for a sensible default. * @return static */ public function next(?int $dayOfWeek = null): static @@ -837,7 +838,8 @@ public function next(?int $dayOfWeek = null): static * of the current day of the week. Use the supplied consts * to indicate the desired dayOfWeek, ex. Chronos::MONDAY. * - * @param int|null $dayOfWeek The day of the week to move to. + * @param int|null $dayOfWeek The day of the week (use Chronos::MONDAY through + * Chronos::SUNDAY), or null for a sensible default. * @return static */ public function previous(?int $dayOfWeek = null): static @@ -857,7 +859,8 @@ public function previous(?int $dayOfWeek = null): static * first day of the current month. Use the supplied consts * to indicate the desired dayOfWeek, ex. Chronos::MONDAY. * - * @param int|null $dayOfWeek The day of the week to move to. + * @param int|null $dayOfWeek The day of the week (use Chronos::MONDAY through + * Chronos::SUNDAY), or null for a sensible default. * @return static */ public function firstOfMonth(?int $dayOfWeek = null): static @@ -873,7 +876,8 @@ public function firstOfMonth(?int $dayOfWeek = null): static * last day of the current month. Use the supplied consts * to indicate the desired dayOfWeek, ex. Chronos::MONDAY. * - * @param int|null $dayOfWeek The day of the week to move to. + * @param int|null $dayOfWeek The day of the week (use Chronos::MONDAY through + * Chronos::SUNDAY), or null for a sensible default. * @return static */ public function lastOfMonth(?int $dayOfWeek = null): static @@ -916,7 +920,8 @@ public function nthOfMonth(int $nth, int $dayOfWeek): static|false * first day of the current quarter. Use the supplied consts * to indicate the desired dayOfWeek, ex. Chronos::MONDAY. * - * @param int|null $dayOfWeek The day of the week to move to. + * @param int|null $dayOfWeek The day of the week (use Chronos::MONDAY through + * Chronos::SUNDAY), or null for a sensible default. * @return static */ public function firstOfQuarter(?int $dayOfWeek = null): static @@ -933,7 +938,8 @@ public function firstOfQuarter(?int $dayOfWeek = null): static * last day of the current quarter. Use the supplied consts * to indicate the desired dayOfWeek, ex. Chronos::MONDAY. * - * @param int|null $dayOfWeek The day of the week to move to. + * @param int|null $dayOfWeek The day of the week (use Chronos::MONDAY through + * Chronos::SUNDAY), or null for a sensible default. * @return static */ public function lastOfQuarter(?int $dayOfWeek = null): static @@ -976,7 +982,8 @@ public function nthOfQuarter(int $nth, int $dayOfWeek): static|false * first day of the current year. Use the supplied consts * to indicate the desired dayOfWeek, ex. Chronos::MONDAY. * - * @param int|null $dayOfWeek The day of the week to move to. + * @param int|null $dayOfWeek The day of the week (use Chronos::MONDAY through + * Chronos::SUNDAY), or null for a sensible default. * @return static */ public function firstOfYear(?int $dayOfWeek = null): static @@ -992,7 +999,8 @@ public function firstOfYear(?int $dayOfWeek = null): static * last day of the current year. Use the supplied consts * to indicate the desired dayOfWeek, ex. Chronos::MONDAY. * - * @param int|null $dayOfWeek The day of the week to move to. + * @param int|null $dayOfWeek The day of the week (use Chronos::MONDAY through + * Chronos::SUNDAY), or null for a sensible default. * @return static */ public function lastOfYear(?int $dayOfWeek = null): static