1616use WizDevelop \PhpValueObject \ValueObjectMeta ;
1717
1818/**
19+ * @phpstan-type Year int<LocalDate::MIN_YEAR, LocalDate::MAX_YEAR>
20+ * @phpstan-type Month int<1, 12>
21+ * @phpstan-type Day int<1, 31>
22+ *
1923 * ローカル日付を表す値オブジェクト
2024 */
2125#[ValueObjectMeta(name: 'ローカル日付 ' )]
4347
4448 /**
4549 * Avoid new() operator.
46- * @param int $year the year to represent, validated from MIN_YEAR to MAX_YEAR
47- * @param int<1, 12> $month the month, from 1 to 12
48- * @param int<1, 31> $day the day, from 1 to 31
50+ * @param int $year the year to represent, validated from MIN_YEAR to MAX_YEAR
51+ * @param Month $month the month, from 1 to 12
52+ * @param Day $day the day, from 1 to 31
4953 */
5054 final private function __construct (
5155 private int $ year ,
@@ -85,9 +89,9 @@ final public function jsonSerialize(): string
8589 // MARK: factory methods
8690 // -------------------------------------------------------------------------
8791 /**
88- * @param int $year the year to represent, validated from MIN_YEAR to MAX_YEAR
89- * @param int<1, 12> $month the month, from 1 to 12
90- * @param int<1, 31> $day the day, from 1 to 31
92+ * @param int $year the year to represent, validated from MIN_YEAR to MAX_YEAR
93+ * @param Month $month the month, from 1 to 12
94+ * @param Day $day the day, from 1 to 31
9195 */
9296 final public static function of (int $ year , int $ month , int $ day ): static
9397 {
@@ -191,10 +195,10 @@ final public static function ofEpochDay(int $epochDay): static
191195 // Convert march-based values back to January-based.
192196 $ marchMonth0 = intdiv ($ marchDoy0 * 5 + 2 , 153 );
193197
194- /** @var int<1, 12> $month */
198+ /** @var Month $month */
195199 $ month = ($ marchMonth0 + 2 ) % 12 + 1 ;
196200
197- /** @var int<1, 31> $dom */
201+ /** @var Day $dom */
198202 $ dom = $ marchDoy0 - intdiv ($ marchMonth0 * 306 + 5 , 10 ) + 1 ;
199203
200204 $ yearEst += intdiv ($ marchMonth0 , 10 );
@@ -271,8 +275,8 @@ className: static::class,
271275 /**
272276 * 有効な日かどうかを判定
273277 * @param int $year 年
274- * @param int<1, 12> $monthOfYear 月
275- * @param int<1, 31> $dayOfMonth 日
278+ * @param Month $monthOfYear 月
279+ * @param Day $dayOfMonth 日
276280 * @return Result<bool,ValueObjectError>
277281 */
278282 final protected static function isValidDate (int $ year , int $ monthOfYear , int $ dayOfMonth ): Result
@@ -340,7 +344,7 @@ final public function toISOString(): string
340344 }
341345
342346 /**
343- * @return int<self::MIN_YEAR, self::MAX_YEAR>
347+ * @return Year
344348 */
345349 final public function getYear (): int
346350 {
@@ -349,15 +353,15 @@ final public function getYear(): int
349353 }
350354
351355 /**
352- * @return int<1, 12>
356+ * @return Month
353357 */
354358 final public function getMonth (): int
355359 {
356360 return $ this ->month ;
357361 }
358362
359363 /**
360- * @return int<1, 31>
364+ * @return Day
361365 */
362366 final public function getDay (): int
363367 {
@@ -471,7 +475,7 @@ final public function addMonths(int $months): static
471475
472476 $ yearDiff = Math::floorDiv ($ month , 12 );
473477
474- /** @var int<1, 12> $month */
478+ /** @var Month $month */
475479 $ month = Math::floorMod ($ month , 12 ) + 1 ;
476480
477481 $ year = $ this ->year + $ yearDiff ;
@@ -599,17 +603,17 @@ final public function toEpochDay(): int
599603 // MARK: private methods
600604 // -------------------------------------------------------------------------
601605 /**
602- * @return array{0:int<self::MIN_YEAR, self::MAX_YEAR>, 1:int<1, 12>, 2:int<1, 31> }
606+ * @return array{0:Year, 1:Month, 2:Day }
603607 */
604608 private static function extractDate (DateTimeInterface $ value ): array
605609 {
606- /** @var int<self::MIN_YEAR, self::MAX_YEAR> */
610+ /** @var Year */
607611 $ year = (int )$ value ->format ('Y ' );
608612
609- /** @var int<1, 12> */
613+ /** @var Month */
610614 $ month = (int )$ value ->format ('n ' );
611615
612- /** @var int<1, 31> */
616+ /** @var Day */
613617 $ day = (int )$ value ->format ('j ' );
614618
615619 return [$ year , $ month , $ day ];
@@ -618,9 +622,9 @@ private static function extractDate(DateTimeInterface $value): array
618622 /**
619623 * Resolves the date, resolving days past the end of month.
620624 *
621- * @param int $year the year to represent, validated from MIN_YEAR to MAX_YEAR
622- * @param int<1, 12> $month the month-of-year to represent
623- * @param int<1, 31> $day the day-of-month to represent, validated from 1 to 31
625+ * @param int $year the year to represent, validated from MIN_YEAR to MAX_YEAR
626+ * @param Month $month the month-of-year to represent
627+ * @param Day $day the day-of-month to represent, validated from 1 to 31
624628 */
625629 private static function resolvePreviousValid (int $ year , int $ month , int $ day ): static
626630 {
@@ -640,7 +644,7 @@ private static function isLeapYear(int $year): bool
640644 }
641645
642646 /**
643- * @param int<1, 12> $month
647+ * @param Month $month
644648 * @return int<28, 31>
645649 */
646650 private static function lengthOfMonth (int $ year , int $ month ): int
@@ -654,8 +658,8 @@ private static function lengthOfMonth(int $year, int $month): int
654658
655659 /**
656660 * Returns whether this date is the last day of the month.
657- * @param int<1, 12> $month
658- * @param int<1, 31> $day
661+ * @param Month $month
662+ * @param Day $day
659663 */
660664 private static function isEndOfMonth (int $ year , int $ month , int $ day ): bool
661665 {
0 commit comments