diff --git a/src/DayOfWeek.php b/src/DayOfWeek.php index afbd2f8..bc5960a 100644 --- a/src/DayOfWeek.php +++ b/src/DayOfWeek.php @@ -4,6 +4,10 @@ namespace Brick\DateTime; +use Brick\DateTime\Parser\DateTimeParseException; +use Brick\DateTime\Parser\DateTimeParser; +use Brick\DateTime\Parser\DateTimeParseResult; +use Brick\DateTime\Parser\IsoParsers; use JsonSerializable; /** @@ -52,6 +56,35 @@ public static function of(int $dayOfWeek): DayOfWeek return DayOfWeek::get($dayOfWeek); } + /** + * @throws DateTimeException If the day-of-week is not valid. + * @throws DateTimeParseException If required fields are missing from the result. + */ + public static function from(DateTimeParseResult $result): DayOfWeek + { + return DayOfWeek::of( + (int) $result->getField(Field\DayOfWeek::NAME), + ); + } + + /** + * Obtains an instance of `DayOfWeek` from a text string. + * + * @param string $text The text to parse, such as `2007-W48`. + * @param DateTimeParser|null $parser The parser to use, defaults to the ISO 8601 parser. + * + * @throws DateTimeException If the day-of-week is not valid. + * @throws DateTimeParseException If the text string does not follow the expected format. + */ + public static function parse(string $text, ?DateTimeParser $parser = null): DayOfWeek + { + if (! $parser) { + $parser = IsoParsers::dayOfWeek(); + } + + return DayOfWeek::from($parser->parse($text)); + } + /** * Returns the current day-of-week in the given time-zone, according to the given clock. * diff --git a/src/Field/DayOfWeek.php b/src/Field/DayOfWeek.php index 2fb8c34..81a32ea 100644 --- a/src/Field/DayOfWeek.php +++ b/src/Field/DayOfWeek.php @@ -16,6 +16,11 @@ final class DayOfWeek */ public const NAME = 'day-of-week'; + /** + * The regular expression pattern of the ISO 8601 representation. + */ + public const PATTERN = '[0-9]{2}'; + /** * @param int $dayOfWeek The day-of-week to check. * diff --git a/src/Parser/IsoParsers.php b/src/Parser/IsoParsers.php index 590a11a..1f24eb7 100644 --- a/src/Parser/IsoParsers.php +++ b/src/Parser/IsoParsers.php @@ -5,6 +5,7 @@ namespace Brick\DateTime\Parser; use Brick\DateTime\Field\DayOfMonth; +use Brick\DateTime\Field\DayOfWeek; use Brick\DateTime\Field\FractionOfSecond; use Brick\DateTime\Field\HourOfDay; use Brick\DateTime\Field\MinuteOfHour; @@ -241,6 +242,23 @@ public static function monthDay(): PatternParser ->toParser(); } + /** + * Returns a parser for a day-of-week such as `03`. + */ + public static function dayOfWeek(): PatternParser + { + /** @var PatternParser|null $parser */ + static $parser; + + if ($parser) { + return $parser; + } + + return $parser = (new PatternParserBuilder()) + ->appendCapturePattern(DayOfWeek::PATTERN, DayOfWeek::NAME) + ->toParser(); + } + /** * Returns a parser for a time-zone offset such as `Z` or `+01:00`. */ diff --git a/tests/DayOfWeekTest.php b/tests/DayOfWeekTest.php index 1d0650c..48c61b8 100644 --- a/tests/DayOfWeekTest.php +++ b/tests/DayOfWeekTest.php @@ -309,4 +309,28 @@ public function providerToString(): array [DayOfWeek::SUNDAY, 'Sunday'], ]; } + + /** + * @dataProvider providerParse + * + * @param string $string The parse string. + * @param int $expectedDayOfWeek The day-of-week value, from 1 to 7. + */ + public function testParse(string $string, int $expectedDayOfWeek): void + { + self::assertDayOfWeekIs($expectedDayOfWeek, DayOfWeek::parse($string)); + } + + public function providerParse(): array + { + return [ + ['01', 1], + ['02', 2], + ['03', 3], + ['04', 4], + ['05', 5], + ['06', 6], + ['07', 7], + ]; + } }