From 6447ef4d10b0c32d6df40a2eb89164364337d356 Mon Sep 17 00:00:00 2001 From: Dorian Villet Date: Thu, 8 Oct 2026 14:58:08 +0200 Subject: [PATCH] Fix LocalDateTime::plusNanos() and minusNanos() within the same second plusWithOverflow() reused the current time whenever the second-of-day was unchanged, discarding the new nano-of-second. Adding or subtracting nanos that did not cross a second boundary therefore returned the original value: LocalDateTime::parse('2000-01-01T12:34:56.5')->plusNanos(1); // 2000-01-01T12:34:56.5 instead of 2000-01-01T12:34:56.500000001 The shortcut now also requires the nano-of-second to be unchanged. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01Fm9bvgKFasEGzpK48bQrxA --- src/LocalDateTime.php | 4 +++- tests/LocalDateTimeTest.php | 6 ++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/LocalDateTime.php b/src/LocalDateTime.php index 8f15e6f3..9f02c566 100644 --- a/src/LocalDateTime.php +++ b/src/LocalDateTime.php @@ -801,7 +801,9 @@ private function plusWithOverflow(int $hours, int $minutes, int $seconds, int $n $newSoD = Math::floorMod($totSeconds, LocalTime::SECONDS_PER_DAY); $newDate = $this->date->plusDays($totDays); - $newTime = ($newSoD === $curSoD ? $this->time : LocalTime::ofSecondOfDay($newSoD, $newNano)); + $newTime = ($newSoD === $curSoD && $newNano === $this->time->getNano()) + ? $this->time + : LocalTime::ofSecondOfDay($newSoD, $newNano); return new LocalDateTime($newDate, $newTime); } diff --git a/tests/LocalDateTimeTest.php b/tests/LocalDateTimeTest.php index defad826..570c8b97 100644 --- a/tests/LocalDateTimeTest.php +++ b/tests/LocalDateTimeTest.php @@ -870,6 +870,9 @@ public static function providerPlusNanos(): array ['2014-12-31T23:59:58.5', 1500000000, '2015-01-01T00:00'], ['2000-03-01T00:00', -1, '2000-02-29T23:59:59.999999999'], ['2000-01-01T00:00:01', -1999999999, '1999-12-31T23:59:59.000000001'], + ['2000-01-01T12:34:56', 1, '2000-01-01T12:34:56.000000001'], + ['2000-01-01T12:34:56.5', -1, '2000-01-01T12:34:56.499999999'], + ['2000-01-01T12:34:56.5', 86400000000001, '2000-01-02T12:34:56.500000001'], ]; } @@ -1039,6 +1042,9 @@ public static function providerMinusNanos(): array ['2014-12-31T23:59:59.5', -500000000, '2015-01-01T00:00'], ['2001-03-01T00:00', 1, '2001-02-28T23:59:59.999999999'], ['2000-01-01T00:00:00', 999999999, '1999-12-31T23:59:59.000000001'], + ['2000-01-01T12:34:56.5', 1, '2000-01-01T12:34:56.499999999'], + ['2000-01-01T12:34:56.5', -1, '2000-01-01T12:34:56.500000001'], + ['2000-01-02T12:34:56.5', 86400000000001, '2000-01-01T12:34:56.499999999'], ]; }