/** * Returns a copy of this `LocalDateTime` with the specified period added. * * @param integer $hours The hours to add, validated as an integer. May be negative. * @param integer $minutes The minutes to add, validated as an integer. May be negative. * @param integer $seconds The seconds to add, validated as an integer. May be negative. * @param integer $nanos The nanos to add, validated as an integer. May be negative. * @param integer $sign The sign, validated as an integer of value `1` to add or `-1` to subtract. * * @return LocalDateTime The combined result. */ private function plusWithOverflow($hours, $minutes, $seconds, $nanos, $sign) { $totDays = intdiv($hours, LocalTime::HOURS_PER_DAY) + intdiv($minutes, LocalTime::MINUTES_PER_DAY) + intdiv($seconds, LocalTime::SECONDS_PER_DAY); $totDays *= $sign; $totSeconds = $seconds % LocalTime::SECONDS_PER_DAY + $minutes % LocalTime::MINUTES_PER_DAY * LocalTime::SECONDS_PER_MINUTE + $hours % LocalTime::HOURS_PER_DAY * LocalTime::SECONDS_PER_HOUR; $curSoD = $this->time->toSecondOfDay(); $totSeconds = $totSeconds * $sign + $curSoD; $totNanos = $nanos * $sign + $this->time->getNano(); $totSeconds += Math::floorDiv($totNanos, LocalTime::NANOS_PER_SECOND); $newNano = Math::floorMod($totNanos, LocalTime::NANOS_PER_SECOND); $totDays += Math::floorDiv($totSeconds, LocalTime::SECONDS_PER_DAY); $newSoD = Math::floorMod($totSeconds, LocalTime::SECONDS_PER_DAY); $newTime = $newSoD === $curSoD ? $this->time : LocalTime::ofSecondOfDay($newSoD, $newNano); return $this->with($this->date->plusDays($totDays), $newTime); }
/** * Returns a copy of this LocalDate with the specified period in months added. * * If the day-of-month is invalid for the resulting year and month, * it will be changed to the last valid day of the month. * * @param integer $months * * @return LocalDate */ public function plusMonths($months) { $month = $this->month + $months - 1; $yearDiff = Math::floorDiv($month, 12); $month = Math::floorMod($month, 12) + 1; $year = $this->year + $yearDiff; return $this->resolvePreviousValid($year, $month, $this->day); }
/** * @dataProvider providerFloorMod * * @param integer $a The dividend. * @param integer $b The divisor. * @param integer $expected The expected floor modulus result. */ public function testFloorMod($a, $b, $expected) { $this->assertSame($expected, Math::floorMod($a, $b)); }
/** * Returns a copy of this YearMonth with the specified period in months added. * * @param integer $months * * @return YearMonth */ public function plusMonths($months) { $month = $this->month + $months - 1; $yearDiff = Math::floorDiv($month, 12); $month = Math::floorMod($month, 12) + 1; $year = $this->year + $yearDiff; return new YearMonth($year, $month); }
/** * Returns a copy of this LocalTime with the specified period in nanoseconds added. * * @param integer $nanos The seconds to add, may be negative. * * @return LocalTime A LocalTime based on this time with the nanoseconds added. */ public function plusNanos($nanos) { $nanos = Cast::toInteger($nanos); if ($nanos === 0) { return $this; } $divBase = Math::floorDiv($this->nano, LocalTime::NANOS_PER_SECOND); $modBase = Math::floorMod($this->nano, LocalTime::NANOS_PER_SECOND); $divPlus = Math::floorDiv($nanos, LocalTime::NANOS_PER_SECOND); $modPlus = Math::floorMod($nanos, LocalTime::NANOS_PER_SECOND); $diffSeconds = $divBase + $divPlus; $nano = $modBase + $modPlus; if ($nano >= LocalTime::NANOS_PER_SECOND) { $nano -= LocalTime::NANOS_PER_SECOND; $diffSeconds++; } return $this->withNano($nano)->plusSeconds($diffSeconds); }