@@ -330,11 +330,9 @@ public function toDateTime()
330330 * @param DateTimeInterface|self|string|null $datetime
331331 * @param DateTimeZone|string|null $timezone
332332 *
333- * @return void
334- *
335333 * @throws Exception
336334 */
337- public static function setTestNow ($ datetime = null , $ timezone = null , ?string $ locale = null )
335+ public static function setTestNow ($ datetime = null , $ timezone = null , ?string $ locale = null ): void
338336 {
339337 // Reset the test instance
340338 if ($ datetime === null ) {
@@ -757,19 +755,29 @@ public function addCalendarMonths(int $months): static
757755 $ time = clone $ this ;
758756
759757 $ year = (int ) $ time ->getYear ();
760- $ month = (int ) $ time ->getMonth () + $ months ;
758+ $ month = (int ) $ time ->getMonth ();
761759 $ day = (int ) $ time ->getDay ();
762760
763- // Adjust year and month for overflow
764- $ year += intdiv ($ month - 1 , 12 );
765- $ month = (($ month - 1 ) % 12 ) + 1 ;
761+ // Adjust total months since year 0
762+ $ totalMonths = ($ year * 12 + $ month - 1 ) + $ months ;
763+
764+ // Recalculate year and month
765+ $ newYear = intdiv ($ totalMonths , 12 );
766+ $ newMonth = $ totalMonths % 12 + 1 ;
766767
767- // Find the last valid day of the target month
768- $ lastDayOfMonth = cal_days_in_month (CAL_GREGORIAN , $ month , $ year );
768+ // Get last day of new month
769+ $ lastDayOfMonth = cal_days_in_month (CAL_GREGORIAN , $ newMonth , $ newYear );
769770 $ correctedDay = min ($ day , $ lastDayOfMonth );
770771
771- // Return new time instance
772- return static ::create ($ year , $ month , $ correctedDay , (int ) $ this ->getHour (), (int ) $ this ->getMinute (), (int ) $ this ->getSecond (), $ this ->getTimezone (), $ this ->locale );
772+ return static ::create ($ newYear , $ newMonth , $ correctedDay , (int ) $ this ->getHour (), (int ) $ this ->getMinute (), (int ) $ this ->getSecond (), $ this ->getTimezone (), $ this ->locale );
773+ }
774+
775+ /**
776+ * Returns a new Time instance with $months calendar months subtracted from the time
777+ */
778+ public function subCalendarMonths (int $ months ): static
779+ {
780+ return $ this ->addCalendarMonths (-$ months );
773781 }
774782
775783 /**
0 commit comments