Lines 100.00% 11 / 11
Methods 100.00% 7 / 7
Classes 100.00% 1 / 1
Name Lines Methods CRAP
 formatTime 100.00% 1 / 1 100.00% 1 / 1 1
 parseTime 100.00% 4 / 4 100.00% 1 / 1 3
 formatDate 100.00% 1 / 1 100.00% 1 / 1 1
 parseDate 100.00% 1 / 1 100.00% 1 / 1 1
 formatDateTime 100.00% 1 / 1 100.00% 1 / 1 1
 parseDateTime 100.00% 1 / 1 100.00% 1 / 1 1
 parseStrictly 100.00% 2 / 2 100.00% 1 / 1 3
14final class CalendarStateFormat
15{
16    private const string DATE_FORMAT = 'Y-m-d';
17
18    public static function formatTime(TimeOfDay $time): string
19    {
20        return $time->format();
21    }
22
23    public static function parseTime(string $state): ?TimeOfDay
24    {
25        try {
26            $time = TimeOfDay::parse($state);
27        } catch (ScheduleException) {
28            return null;
29        }
30
31        return $time->format() === $state ? $time : null;
32    }
33
34    public static function formatDate(DateTimeInterface $date): string
35    {
36        return $date->format(self::DATE_FORMAT);
37    }
38
39    // Midnight UTC of the day, or null when the state is not a calendar date.
40    public static function parseDate(string $state): ?DateTimeImmutable
41    {
42        return self::parseStrictly('!' . self::DATE_FORMAT, $state, new DateTimeZone('UTC'));
43    }
44
45    public static function formatDateTime(DateTimeInterface $moment): string
46    {
47        return $moment->format(DateTimeInterface::ATOM);
48    }
49
50    public static function parseDateTime(string $state): ?DateTimeImmutable
51    {
52        return self::parseStrictly(DateTimeInterface::ATOM, $state, null);
53    }
54
55    private static function parseStrictly(string $format, string $state, ?DateTimeZone $zone): ?DateTimeImmutable
56    {
57        $parsed = DateTimeImmutable::createFromFormat($format, $state, $zone);
58
59        // Overflowing fields such as month 13 parse with warnings; the round trip rejects them.
60        return $parsed !== false && $parsed->format(ltrim($format, '!')) === $state ? $parsed : null;
61    }
62}