diff --git a/src/Model/TimeRange.php b/src/Model/TimeRange.php index 3471b2a..0f17172 100644 --- a/src/Model/TimeRange.php +++ b/src/Model/TimeRange.php @@ -164,9 +164,26 @@ final readonly class TimeRange implements \Stringable return self::format($this->endMinute); } + /** + * One-sided spans read as "bis 13:00" / "ab 13:00" rather than 00:00–13:00 / 13:00–24:00: + * a half day booked by giving only one end has no meaningful other end, and midnight is not + * what the user typed. + */ public function __toString(): string { - return $this->isAllDay() ? 'ganztägig' : $this->start().'–'.$this->end(); + if ($this->isAllDay()) { + return 'ganztägig'; + } + + if (self::DAY_START === $this->startMinute) { + return 'bis '.$this->end(); + } + + if (self::DAY_END === $this->endMinute) { + return 'ab '.$this->start(); + } + + return $this->start().'–'.$this->end(); } private static function minutesOf(\DateTimeInterface $time): int diff --git a/tests/Controller/FloorPlanTest.php b/tests/Controller/FloorPlanTest.php index 2663573..2504698 100644 --- a/tests/Controller/FloorPlanTest.php +++ b/tests/Controller/FloorPlanTest.php @@ -56,7 +56,7 @@ class FloorPlanTest extends WebTestCase $this->book($desk, $this->user('bea@ep-reisen.de', 'Bea Kranz'), 540, 780); self::assertSame( - ['Schreibtisch 01', 'Bea K. 09:00–13:00', 'frei 13:00–24:00'], + ['Schreibtisch 01', 'Bea K. 09:00–13:00', 'frei ab 13:00'], $this->linesOf($this->board()), ); } @@ -112,7 +112,7 @@ class FloorPlanTest extends WebTestCase $lines = $this->linesOf($this->board()); self::assertSame( - ['Schreibtisch 01', 'Ann A. 00:00–06:00', 'Bea B. 06:00–12:00', '+2 weitere'], + ['Schreibtisch 01', 'Ann A. bis 06:00', 'Bea B. 06:00–12:00', '+2 weitere'], $lines, ); // Label plus MAX_LINES, never more. diff --git a/tests/Model/SpotTest.php b/tests/Model/SpotTest.php index e58b224..1fa38ac 100644 --- a/tests/Model/SpotTest.php +++ b/tests/Model/SpotTest.php @@ -42,7 +42,7 @@ class SpotTest extends TestCase // Taken 09:00-13:00 leaves 00:00-09:00 (9h) and 13:00-24:00 (11h). $spot = $this->spot([$this->booking($this->someoneElse(), 540, 780)]); - self::assertSame('13:00–24:00', (string) $spot->suggested()); + self::assertSame('ab 13:00', (string) $spot->suggested()); } public function testTheSuggestedWindowIsAlwaysBookable(): void diff --git a/tests/Model/TimeRangeTest.php b/tests/Model/TimeRangeTest.php index 5952efd..603c1a0 100644 --- a/tests/Model/TimeRangeTest.php +++ b/tests/Model/TimeRangeTest.php @@ -149,6 +149,14 @@ class TimeRangeTest extends TestCase self::assertSame('yes', $twig->render('t', ['range' => TimeRange::wholeDay()])); } + public function testAOneSidedRangeReadsAsAbOrBis(): void + { + self::assertSame('bis 13:00', (string) TimeRange::fromMinutes(TimeRange::DAY_START, 13 * 60)); + self::assertSame('ab 13:00', (string) TimeRange::fromMinutes(13 * 60, TimeRange::DAY_END)); + self::assertSame('09:00–13:00', (string) TimeRange::fromMinutes(9 * 60, 13 * 60)); + self::assertSame('ganztägig', (string) TimeRange::wholeDay()); + } + /** * @param list $ranges *