Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
5 / 5
CRAP
100.00% covered (success)
100.00%
1 / 1
DateRange
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
5 / 5
7
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
 fromIso
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 start
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 end
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 equals
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3declare(strict_types=1);
4
5namespace App\Shared\Domain\ValueObject;
6
7use DateTimeImmutable;
8use InvalidArgumentException;
9
10/**
11 * Inclusive date range. End must not precede start. Time component is irrelevant
12 * (dates are normalised to midnight when built from ISO strings).
13 */
14final class DateRange
15{
16    public function __construct(
17        private readonly DateTimeImmutable $start,
18        private readonly DateTimeImmutable $end,
19    ) {
20        if ($end < $start) {
21            throw new InvalidArgumentException(sprintf('End date <%s> cannot precede start date <%s>.', $end->format('Y-m-d'), $start->format('Y-m-d')));
22        }
23    }
24
25    public static function fromIso(string $start, string $end): self
26    {
27        return new self(IsoDate::parse($start), IsoDate::parse($end));
28    }
29
30    public function start(): DateTimeImmutable
31    {
32        return $this->start;
33    }
34
35    public function end(): DateTimeImmutable
36    {
37        return $this->end;
38    }
39
40    public function equals(self $other): bool
41    {
42        return $this->start == $other->start && $this->end == $other->end;
43    }
44}