16
16
use WizDevelop \PhpValueObject \ValueObjectMeta ;
17
17
18
18
/**
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
+ *
19
23
* ローカル日付を表す値オブジェクト
20
24
*/
21
25
#[ValueObjectMeta(name: 'ローカル日付 ' )]
43
47
44
48
/**
45
49
* 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
49
53
*/
50
54
final private function __construct (
51
55
private int $ year ,
@@ -85,9 +89,9 @@ final public function jsonSerialize(): string
85
89
// MARK: factory methods
86
90
// -------------------------------------------------------------------------
87
91
/**
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
91
95
*/
92
96
final public static function of (int $ year , int $ month , int $ day ): static
93
97
{
@@ -191,10 +195,10 @@ final public static function ofEpochDay(int $epochDay): static
191
195
// Convert march-based values back to January-based.
192
196
$ marchMonth0 = intdiv ($ marchDoy0 * 5 + 2 , 153 );
193
197
194
- /** @var int<1, 12> $month */
198
+ /** @var Month $month */
195
199
$ month = ($ marchMonth0 + 2 ) % 12 + 1 ;
196
200
197
- /** @var int<1, 31> $dom */
201
+ /** @var Day $dom */
198
202
$ dom = $ marchDoy0 - intdiv ($ marchMonth0 * 306 + 5 , 10 ) + 1 ;
199
203
200
204
$ yearEst += intdiv ($ marchMonth0 , 10 );
@@ -271,8 +275,8 @@ className: static::class,
271
275
/**
272
276
* 有効な日かどうかを判定
273
277
* @param int $year 年
274
- * @param int<1, 12> $monthOfYear 月
275
- * @param int<1, 31> $dayOfMonth 日
278
+ * @param Month $monthOfYear 月
279
+ * @param Day $dayOfMonth 日
276
280
* @return Result<bool,ValueObjectError>
277
281
*/
278
282
final protected static function isValidDate (int $ year , int $ monthOfYear , int $ dayOfMonth ): Result
@@ -340,7 +344,7 @@ final public function toISOString(): string
340
344
}
341
345
342
346
/**
343
- * @return int<self::MIN_YEAR, self::MAX_YEAR>
347
+ * @return Year
344
348
*/
345
349
final public function getYear (): int
346
350
{
@@ -349,15 +353,15 @@ final public function getYear(): int
349
353
}
350
354
351
355
/**
352
- * @return int<1, 12>
356
+ * @return Month
353
357
*/
354
358
final public function getMonth (): int
355
359
{
356
360
return $ this ->month ;
357
361
}
358
362
359
363
/**
360
- * @return int<1, 31>
364
+ * @return Day
361
365
*/
362
366
final public function getDay (): int
363
367
{
@@ -471,7 +475,7 @@ final public function addMonths(int $months): static
471
475
472
476
$ yearDiff = Math::floorDiv ($ month , 12 );
473
477
474
- /** @var int<1, 12> $month */
478
+ /** @var Month $month */
475
479
$ month = Math::floorMod ($ month , 12 ) + 1 ;
476
480
477
481
$ year = $ this ->year + $ yearDiff ;
@@ -599,17 +603,17 @@ final public function toEpochDay(): int
599
603
// MARK: private methods
600
604
// -------------------------------------------------------------------------
601
605
/**
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 }
603
607
*/
604
608
private static function extractDate (DateTimeInterface $ value ): array
605
609
{
606
- /** @var int<self::MIN_YEAR, self::MAX_YEAR> */
610
+ /** @var Year */
607
611
$ year = (int )$ value ->format ('Y ' );
608
612
609
- /** @var int<1, 12> */
613
+ /** @var Month */
610
614
$ month = (int )$ value ->format ('n ' );
611
615
612
- /** @var int<1, 31> */
616
+ /** @var Day */
613
617
$ day = (int )$ value ->format ('j ' );
614
618
615
619
return [$ year , $ month , $ day ];
@@ -618,9 +622,9 @@ private static function extractDate(DateTimeInterface $value): array
618
622
/**
619
623
* Resolves the date, resolving days past the end of month.
620
624
*
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
624
628
*/
625
629
private static function resolvePreviousValid (int $ year , int $ month , int $ day ): static
626
630
{
@@ -640,7 +644,7 @@ private static function isLeapYear(int $year): bool
640
644
}
641
645
642
646
/**
643
- * @param int<1, 12> $month
647
+ * @param Month $month
644
648
* @return int<28, 31>
645
649
*/
646
650
private static function lengthOfMonth (int $ year , int $ month ): int
@@ -654,8 +658,8 @@ private static function lengthOfMonth(int $year, int $month): int
654
658
655
659
/**
656
660
* 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
659
663
*/
660
664
private static function isEndOfMonth (int $ year , int $ month , int $ day ): bool
661
665
{
0 commit comments