From 9d1e2ef85ac8079a7c87b148846eecba99b84eca Mon Sep 17 00:00:00 2001 From: Dorian Villet Date: Sat, 30 Mar 2024 10:09:21 +0100 Subject: [PATCH 1/5] MonthDay::of() / MonthDay::withMonth() allows Month enum --- src/MonthDay.php | 25 ++++++++++++++++++------- tests/MonthDayTest.php | 8 +++++--- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/src/MonthDay.php b/src/MonthDay.php index 68e3611..1731c10 100644 --- a/src/MonthDay.php +++ b/src/MonthDay.php @@ -11,6 +11,8 @@ use JsonSerializable; use Stringable; +use function is_int; + /** * A month-day in the ISO-8601 calendar system, such as `--12-03`. */ @@ -31,14 +33,19 @@ private function __construct( /** * Obtains an instance of MonthDay. * - * @param int $month The month-of-year, from 1 (January) to 12 (December). - * @param int $day The day-of-month, from 1 to 31. + * @param int|Month $month The month-of-year, from 1 (January) to 12 (December). + * @param int $day The day-of-month, from 1 to 31. * * @throws DateTimeException If the month-day is not valid. */ - public static function of(int $month, int $day): MonthDay + public static function of(Month|int $month, int $day): MonthDay { - Field\MonthOfYear::check($month); + if (is_int($month)) { + Field\MonthOfYear::check($month); + } else { + $month = $month->value; + } + Field\DayOfMonth::check($day, $month); return new MonthDay($month, $day); @@ -187,14 +194,18 @@ public function isValidYear(int $year): bool * * @throws DateTimeException If the month is invalid. */ - public function withMonth(int $month): MonthDay + public function withMonth(Month|int $month): MonthDay { + if (is_int($month)) { + Field\MonthOfYear::check($month); + } else { + $month = $month->value; + } + if ($month === $this->month) { return $this; } - Field\MonthOfYear::check($month); - $lastDay = Field\MonthOfYear::getLength($month); return new MonthDay($month, ($lastDay < $this->day) ? $lastDay : $this->day); diff --git a/tests/MonthDayTest.php b/tests/MonthDayTest.php index d4b085d..dd4217f 100644 --- a/tests/MonthDayTest.php +++ b/tests/MonthDayTest.php @@ -7,6 +7,7 @@ use Brick\DateTime\Clock\FixedClock; use Brick\DateTime\DateTimeException; use Brick\DateTime\Instant; +use Brick\DateTime\Month; use Brick\DateTime\MonthDay; use Brick\DateTime\Parser\DateTimeParseException; use Brick\DateTime\TimeZone; @@ -25,6 +26,7 @@ class MonthDayTest extends AbstractTestCase public function testOf(int $month, int $day): void { self::assertMonthDayIs($month, $day, MonthDay::of($month, $day)); + self::assertMonthDayIs($month, $day, MonthDay::of(Month::from($month), $day)); } public static function providerOf(): array @@ -278,10 +280,10 @@ public static function providerIsValidYear(): array public function testWithMonth(int $month, int $day, int $newMonth, int $expectedDay): void { $monthDay = MonthDay::of($month, $day); - $newMonthDay = $monthDay->withMonth($newMonth); - self::assertMonthDayIs($month, $day, $monthDay); - self::assertMonthDayIs($newMonth, $expectedDay, $newMonthDay); + + self::assertMonthDayIs($newMonth, $expectedDay, $monthDay->withMonth($newMonth)); + self::assertMonthDayIs($newMonth, $expectedDay, $monthDay->withMonth(Month::from($newMonth))); } public static function providerWithMonth(): array From 55ff14611e8512fdb31657570566a748c3c246aa Mon Sep 17 00:00:00 2001 From: Dorian Villet Date: Sat, 30 Mar 2024 10:18:33 +0100 Subject: [PATCH 2/5] LocalDate::of() / LocalDate::withMonth() allows Month enum --- src/LocalDate.php | 27 +++++++++++++++++++-------- tests/LocalDateTest.php | 6 ++++-- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/src/LocalDate.php b/src/LocalDate.php index b5ee4cb..e8cc497 100644 --- a/src/LocalDate.php +++ b/src/LocalDate.php @@ -16,6 +16,7 @@ use Stringable; use function intdiv; +use function is_int; use function min; use function str_pad; @@ -65,16 +66,22 @@ private function __construct( /** * Obtains an instance of `LocalDate` from a year, month and day. * - * @param int $year The year, from MIN_YEAR to MAX_YEAR. - * @param int $month The month-of-year, from 1 (January) to 12 (December). - * @param int $day The day-of-month, from 1 to 31. + * @param int $year The year, from MIN_YEAR to MAX_YEAR. + * @param int|Month $month The month-of-year, from 1 (January) to 12 (December). + * @param int $day The day-of-month, from 1 to 31. * * @throws DateTimeException If the date is not valid. */ - public static function of(int $year, int $month, int $day): LocalDate + public static function of(int $year, Month|int $month, int $day): LocalDate { Field\Year::check($year); - Field\MonthOfYear::check($month); + + if (is_int($month)) { + Field\MonthOfYear::check($month); + } else { + $month = $month->value; + } + Field\DayOfMonth::check($day, $month, $year); return new LocalDate($year, $month, $day); @@ -382,14 +389,18 @@ public function withYear(int $year): LocalDate * * @throws DateTimeException If the month is invalid. */ - public function withMonth(int $month): LocalDate + public function withMonth(Month|int $month): LocalDate { + if (is_int($month)) { + Field\MonthOfYear::check($month); + } else { + $month = $month->value; + } + if ($month === $this->month) { return $this; } - Field\MonthOfYear::check($month); - return $this->resolvePreviousValid($this->year, $month, $this->day); } diff --git a/tests/LocalDateTest.php b/tests/LocalDateTest.php index b0c7e7f..e8cbbd5 100644 --- a/tests/LocalDateTest.php +++ b/tests/LocalDateTest.php @@ -10,6 +10,7 @@ use Brick\DateTime\Instant; use Brick\DateTime\LocalDate; use Brick\DateTime\LocalTime; +use Brick\DateTime\Month; use Brick\DateTime\Period; use Brick\DateTime\TimeZone; use Brick\DateTime\Year; @@ -31,6 +32,7 @@ class LocalDateTest extends AbstractTestCase public function testOf(): void { self::assertLocalDateIs(2007, 7, 15, LocalDate::of(2007, 7, 15)); + self::assertLocalDateIs(2007, 7, 15, LocalDate::of(2007, Month::JULY, 15)); } /** @@ -526,8 +528,8 @@ public static function providerWithInvalidYearThrowsException(): array #[DataProvider('providerWithMonth')] public function testWithMonth(int $year, int $month, int $day, int $newMonth, int $expectedDay): void { - $localDate = LocalDate::of($year, $month, $day)->withMonth($newMonth); - self::assertLocalDateIs($year, $newMonth, $expectedDay, $localDate); + self::assertLocalDateIs($year, $newMonth, $expectedDay, LocalDate::of($year, $month, $day)->withMonth($newMonth)); + self::assertLocalDateIs($year, $newMonth, $expectedDay, LocalDate::of($year, $month, $day)->withMonth(Month::from($newMonth))); } public static function providerWithMonth(): array From 26c7fae0ef09b9b2c616dad4065c907713adabc6 Mon Sep 17 00:00:00 2001 From: Dorian Villet Date: Sat, 30 Mar 2024 10:19:25 +0100 Subject: [PATCH 3/5] LocalDateTime::of() / LocalDateTime::withMonth() allows Month enum --- src/LocalDateTime.php | 18 +++++++++--------- tests/LocalDateTimeTest.php | 12 ++++++------ 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/LocalDateTime.php b/src/LocalDateTime.php index 2a2727a..62c159d 100644 --- a/src/LocalDateTime.php +++ b/src/LocalDateTime.php @@ -31,17 +31,17 @@ public function __construct( } /** - * @param int $year The year, from MIN_YEAR to MAX_YEAR. - * @param int $month The month-of-year, from 1 (January) to 12 (December). - * @param int $day The day-of-month, from 1 to 31. - * @param int $hour The hour-of-day, from 0 to 23. - * @param int $minute The minute-of-hour, from 0 to 59. - * @param int $second The second-of-minute, from 0 to 59. - * @param int $nano The nano-of-second, from 0 to 999,999,999. + * @param int $year The year, from MIN_YEAR to MAX_YEAR. + * @param int|Month $month The month-of-year, from 1 (January) to 12 (December). + * @param int $day The day-of-month, from 1 to 31. + * @param int $hour The hour-of-day, from 0 to 23. + * @param int $minute The minute-of-hour, from 0 to 59. + * @param int $second The second-of-minute, from 0 to 59. + * @param int $nano The nano-of-second, from 0 to 999,999,999. * * @throws DateTimeException If the date or time is not valid. */ - public static function of(int $year, int $month, int $day, int $hour = 0, int $minute = 0, int $second = 0, int $nano = 0): LocalDateTime + public static function of(int $year, Month|int $month, int $day, int $hour = 0, int $minute = 0, int $second = 0, int $nano = 0): LocalDateTime { $date = LocalDate::of($year, $month, $day); $time = LocalTime::of($hour, $minute, $second, $nano); @@ -306,7 +306,7 @@ public function withYear(int $year): LocalDateTime * * @throws DateTimeException If the month is invalid. */ - public function withMonth(int $month): LocalDateTime + public function withMonth(Month|int $month): LocalDateTime { $date = $this->date->withMonth($month); diff --git a/tests/LocalDateTimeTest.php b/tests/LocalDateTimeTest.php index 1d1dae8..90e2f42 100644 --- a/tests/LocalDateTimeTest.php +++ b/tests/LocalDateTimeTest.php @@ -13,6 +13,7 @@ use Brick\DateTime\LocalDate; use Brick\DateTime\LocalDateTime; use Brick\DateTime\LocalTime; +use Brick\DateTime\Month; use Brick\DateTime\Parser\DateTimeParseException; use Brick\DateTime\Period; use Brick\DateTime\TimeZone; @@ -32,10 +33,8 @@ class LocalDateTimeTest extends AbstractTestCase { public function testOf(): void { - $date = LocalDate::of(2001, 12, 23); - $time = LocalTime::of(12, 34, 56, 987654321); - - self::assertLocalDateTimeIs(2001, 12, 23, 12, 34, 56, 987654321, new LocalDateTime($date, $time)); + self::assertLocalDateTimeIs(2001, 12, 23, 12, 34, 56, 987654321, LocalDateTime::of(2001, 12, 23, 12, 34, 56, 987654321)); + self::assertLocalDateTimeIs(2001, 12, 23, 12, 34, 56, 987654321, LocalDateTime::of(2001, Month::DECEMBER, 23, 12, 34, 56, 987654321)); } public function testFromNativeDateTime(): void @@ -351,8 +350,9 @@ public function testWithMonth(int $year, int $month, int $day, int $newMonth, in { $date = LocalDate::of($year, $month, $day); $time = LocalTime::of(1, 2, 3, 123456789); - $localDateTime = $date->atTime($time)->withMonth($newMonth); - self::assertLocalDateTimeIs($year, $newMonth, $expectedDay, 1, 2, 3, 123456789, $localDateTime); + + self::assertLocalDateTimeIs($year, $newMonth, $expectedDay, 1, 2, 3, 123456789, $date->atTime($time)->withMonth($newMonth)); + self::assertLocalDateTimeIs($year, $newMonth, $expectedDay, 1, 2, 3, 123456789, $date->atTime($time)->withMonth(Month::from($newMonth))); } public static function providerWithMonth(): array From d4919a023bd6d76d31cf1f54825175271ca8402c Mon Sep 17 00:00:00 2001 From: Dorian Villet Date: Sat, 30 Mar 2024 10:20:03 +0100 Subject: [PATCH 4/5] ZonedDateTime::withMonth() allows Month enum --- src/ZonedDateTime.php | 2 +- tests/ZonedDateTimeTest.php | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ZonedDateTime.php b/src/ZonedDateTime.php index be3682d..d62c28c 100644 --- a/src/ZonedDateTime.php +++ b/src/ZonedDateTime.php @@ -347,7 +347,7 @@ public function withYear(int $year): ZonedDateTime /** * Returns a copy of this ZonedDateTime with the month-of-year altered. */ - public function withMonth(int $month): ZonedDateTime + public function withMonth(Month|int $month): ZonedDateTime { return ZonedDateTime::of($this->localDateTime->withMonth($month), $this->timeZone); } diff --git a/tests/ZonedDateTimeTest.php b/tests/ZonedDateTimeTest.php index 3f859a3..cc61a23 100644 --- a/tests/ZonedDateTimeTest.php +++ b/tests/ZonedDateTimeTest.php @@ -12,6 +12,7 @@ use Brick\DateTime\LocalDate; use Brick\DateTime\LocalDateTime; use Brick\DateTime\LocalTime; +use Brick\DateTime\Month; use Brick\DateTime\Parser\DateTimeParseException; use Brick\DateTime\Period; use Brick\DateTime\TimeZone; @@ -581,6 +582,7 @@ public function testWithYear(): void public function testWithMonth(): void { self::assertIs(ZonedDateTime::class, '2000-07-20T12:34:56.123456789-07:00[America/Los_Angeles]', $this->getTestZonedDateTime()->withMonth(7)); + self::assertIs(ZonedDateTime::class, '2000-07-20T12:34:56.123456789-07:00[America/Los_Angeles]', $this->getTestZonedDateTime()->withMonth(Month::JULY)); } public function testWithDay(): void From 0444037b950cada1c9cf69cc8698a8f6b6edf85b Mon Sep 17 00:00:00 2001 From: Dorian Villet Date: Sat, 30 Mar 2024 10:21:21 +0100 Subject: [PATCH 5/5] Use Month enum internally where appropriate. --- src/Field/WeekOfYear.php | 3 ++- src/LocalDate.php | 6 +++--- src/LocalTime.php | 2 +- src/Year.php | 4 ++-- src/YearWeek.php | 2 +- 5 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/Field/WeekOfYear.php b/src/Field/WeekOfYear.php index 2d115ef..e2ef605 100644 --- a/src/Field/WeekOfYear.php +++ b/src/Field/WeekOfYear.php @@ -7,6 +7,7 @@ use Brick\DateTime\DateTimeException; use Brick\DateTime\DayOfWeek; use Brick\DateTime\LocalDate; +use Brick\DateTime\Month; /** * The week-of-year field. @@ -51,7 +52,7 @@ public static function check(int $weekOfYear, ?int $year = null): void */ public static function is53WeekYear(int $year): bool { - $date = LocalDate::of($year, 1, 1); + $date = LocalDate::of($year, Month::JANUARY, 1); $dayOfWeek = $date->getDayOfWeek(); return $dayOfWeek === DayOfWeek::THURSDAY diff --git a/src/LocalDate.php b/src/LocalDate.php index e8cc497..a267b7a 100644 --- a/src/LocalDate.php +++ b/src/LocalDate.php @@ -111,7 +111,7 @@ public static function ofYearDay(int $year, int $dayOfYear): LocalDate $dayOfMonth = $dayOfYear - $monthOfYear->getFirstDayOfYear($isLeap) + 1; - return LocalDate::of($year, $monthOfYear->value, $dayOfMonth); + return LocalDate::of($year, $monthOfYear, $dayOfMonth); } /** @@ -223,7 +223,7 @@ public static function min(): LocalDate return $min; } - return $min = LocalDate::of(self::MIN_YEAR, 1, 1); + return $min = LocalDate::of(self::MIN_YEAR, Month::JANUARY, 1); } /** @@ -240,7 +240,7 @@ public static function max(): LocalDate return $max; } - return $max = LocalDate::of(self::MAX_YEAR, 12, 31); + return $max = LocalDate::of(self::MAX_YEAR, Month::DECEMBER, 31); } /** diff --git a/src/LocalTime.php b/src/LocalTime.php index 8f5b472..5fdd884 100644 --- a/src/LocalTime.php +++ b/src/LocalTime.php @@ -607,7 +607,7 @@ public function toSecondOfDay(): int */ public function toNativeDateTime(): DateTime { - return $this->atDate(LocalDate::of(0, 1, 1))->toNativeDateTime(); + return $this->atDate(LocalDate::of(0, Month::JANUARY, 1))->toNativeDateTime(); } /** diff --git a/src/Year.php b/src/Year.php index 143ccc9..9fd6c99 100644 --- a/src/Year.php +++ b/src/Year.php @@ -274,8 +274,8 @@ public function atMonthDay(MonthDay $monthDay): LocalDate public function toLocalDateRange(): LocalDateRange { return LocalDateRange::of( - $this->atMonth(1)->getFirstDay(), - $this->atMonth(12)->getLastDay(), + $this->atMonth(Month::JANUARY)->getFirstDay(), + $this->atMonth(Month::DECEMBER)->getLastDay(), ); } diff --git a/src/YearWeek.php b/src/YearWeek.php index 2828606..2e237b3 100644 --- a/src/YearWeek.php +++ b/src/YearWeek.php @@ -206,7 +206,7 @@ public function atDay(DayOfWeek|int $dayOfWeek): LocalDate $dayOfWeek = DayOfWeek::from($dayOfWeek); } - $correction = LocalDate::of($this->year, 1, 4)->getDayOfWeek()->value + 3; + $correction = LocalDate::of($this->year, Month::JANUARY, 4)->getDayOfWeek()->value + 3; $dayOfYear = $this->week * 7 + $dayOfWeek->value - $correction; $maxDaysOfYear = Field\Year::isLeap($this->year) ? 366 : 365;