Lines
100.00%
11 / 11
Functions and Methods
100.00%
7 / 7
Classes and Traits
100.00%
1 / 1
| Name | Lines | Functions and Methods | CRAP | Classes and Traits | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| CalendarStateFormat | 100.00% | 11 / 11 | 100.00% | 7 / 7 | 11 | 100.00% | 1 / 1 | |||
| 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 | |||||
| 1 | <?php | |
| 2 | ||
| 3 | declare(strict_types=1); | |
| 4 | ||
| 5 | namespace Stewart\Contracts\Exposure; | |
| 6 | ||
| 7 | use DateTimeImmutable; | |
| 8 | use DateTimeInterface; | |
| 9 | use DateTimeZone; | |
| 10 | use Stewart\Contracts\Exception\ScheduleException; | |
| 11 | use Stewart\Contracts\Schedule\TimeOfDay; | |
| 12 | ||
| 13 | /** @internal */ | |
| 14 | final 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 | } |