diff --git a/src/Rule/TimeRule.php b/src/Rule/TimeRule.php new file mode 100644 index 0000000..34c23f0 --- /dev/null +++ b/src/Rule/TimeRule.php @@ -0,0 +1,62 @@ + 02:49 and 0 to the right of the + * minutes ans seconds so 3:4 => 03:40:00 + */ +class TimeRule extends AbstractRule +{ + + public const TIME_REGEX = '/^([0-1]{1}[0-9]{1}|[2]{1}[0-3]{1}):[0-5]{1}[0-9]{1}:[0-5]{1}[0-9]{1}$/'; + + public function validate(): int + { + $run = parent::validate(); + + if ($run !== RuleInterface::CHECK) { + return $run; + } + + if (! static::checkTime($this->value)) { + $this->error = "{$this->key}: {$this->value} is not a valid time"; + return RuleInterface::ERROR; + } + + return RuleInterface::VALID; + } + + /** + * Check if a given time has the following format: + * hh:mm:ss or hh:mm + * + * @param string $time Time to be checked. + * + * @return bool + */ + public static function checkTime($time): bool + { + $tokens = explode(':', $time); + + $count = count($tokens); + if ($count < 2 || $count > 3) { + // time must be hh:mm or hh:mm:ss + return false; + } + + // seconds are optional + $second = ($count == 3) ? $tokens[2] : '0'; + + // We put time in hh:mm:ss format with padding + $time = str_pad($tokens[0], 2, '0', STR_PAD_LEFT) . ':' + . str_pad($tokens[1], 2, '0', STR_PAD_RIGHT) . ':' + . str_pad($second, 2, '0', STR_PAD_RIGHT); + + // we test hh:mm:ss from 00:00:00 => 23:59:59 + return !! preg_match(self::TIME_REGEX, $time); + } +} diff --git a/tests/Rule/TimeRuleTest.php b/tests/Rule/TimeRuleTest.php new file mode 100644 index 0000000..bc550d1 --- /dev/null +++ b/tests/Rule/TimeRuleTest.php @@ -0,0 +1,56 @@ +validate(); + + assertThat($res, identicalTo($expectedResult)); + + assertThat($rule->getError(), identicalTo($expectedError)); + } + + public function getTimeValueProvider(): \Generator + { + yield 'Given value could be empty' => [ + '', RuleInterface::VALID, '' + ]; + + yield 'Given time 22:25 should be valid' => [ + '22:25', RuleInterface::VALID, '' + ]; + + yield 'Given time 22:25:38 should be valid' => [ + '22:25:38', RuleInterface::VALID, '' + ]; + + yield 'Given time 8:2:4 should be valid' => [ + '8:2:4', RuleInterface::VALID, '' + ]; + + yield 'Given time 25:2 should not be valid' => [ + '25:2', RuleInterface::ERROR, 'time: 25:2 is not a valid time' + ]; + + yield 'Given time 21 should not be valid' => [ + '21', RuleInterface::ERROR, 'time: 21 is not a valid time' + ]; + + yield 'Given time 20:2:3:6 should not be valid' => [ + '20:2:3:6', RuleInterface::ERROR, 'time: 20:2:3:6 is not a valid time' + ]; + } +}