From 724983c72123f60428f9ebb116039a73befd6b00 Mon Sep 17 00:00:00 2001 From: mscherer Date: Sat, 14 Mar 2026 18:52:08 +0100 Subject: [PATCH] Add startOfHour() and endOfHour() methods to ChronosTime Adds boundary methods to ChronosTime for resetting to hour boundaries: - startOfHour(): Resets to the start of the current hour (X:00:00.000000) - endOfHour(): Sets to the end of the current hour (X:59:59.999999) --- src/ChronosTime.php | 31 ++++++++++++++++++++++++++++++ tests/TestCase/ChronosTimeTest.php | 30 +++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) diff --git a/src/ChronosTime.php b/src/ChronosTime.php index 7d65dd2..bbcc64b 100644 --- a/src/ChronosTime.php +++ b/src/ChronosTime.php @@ -325,6 +325,37 @@ public function setTime(int $hours = 0, int $minutes = 0, int $seconds = 0, int return $clone; } + /** + * Resets time to the start of the current hour. + * + * @return static + */ + public function startOfHour(): static + { + $hourTicks = $this->ticks - $this->ticks % self::TICKS_PER_HOUR; + + $clone = clone $this; + $clone->ticks = $hourTicks; + + return $clone; + } + + /** + * Sets time to the end of the current hour. + * + * @return static + */ + public function endOfHour(): static + { + $hourTicks = $this->ticks - $this->ticks % self::TICKS_PER_HOUR; + $endTicks = $hourTicks + self::TICKS_PER_HOUR - 1; + + $clone = clone $this; + $clone->ticks = $endTicks; + + return $clone; + } + /** * @param int $a Left side * @param int $a Right side diff --git a/tests/TestCase/ChronosTimeTest.php b/tests/TestCase/ChronosTimeTest.php index 92b6786..8ab93f8 100644 --- a/tests/TestCase/ChronosTimeTest.php +++ b/tests/TestCase/ChronosTimeTest.php @@ -193,6 +193,36 @@ public function testSetTime(): void $this->assertSame('01:00:00.000001', $t->format('H:i:s.u')); } + public function testStartOfHour(): void + { + $t = ChronosTime::parse('12:30:45.123456'); + $start = $t->startOfHour(); + + $this->assertNotSame($t, $start); + $this->assertSame('12:00:00.000000', $start->format('H:i:s.u')); + + $t = ChronosTime::parse('00:59:59.999999'); + $this->assertSame('00:00:00.000000', $t->startOfHour()->format('H:i:s.u')); + + $t = ChronosTime::parse('23:01:01'); + $this->assertSame('23:00:00.000000', $t->startOfHour()->format('H:i:s.u')); + } + + public function testEndOfHour(): void + { + $t = ChronosTime::parse('12:30:45.123456'); + $end = $t->endOfHour(); + + $this->assertNotSame($t, $end); + $this->assertSame('12:59:59.999999', $end->format('H:i:s.u')); + + $t = ChronosTime::parse('00:00:00'); + $this->assertSame('00:59:59.999999', $t->endOfHour()->format('H:i:s.u')); + + $t = ChronosTime::parse('23:30:00'); + $this->assertSame('23:59:59.999999', $t->endOfHour()->format('H:i:s.u')); + } + public function testFormat(): void { $t = new ChronosTime('23:59:59.999999');