diff --git a/library/Rules/Date.php b/library/Rules/Date.php index eb47d16d..342e1d43 100644 --- a/library/Rules/Date.php +++ b/library/Rules/Date.php @@ -49,8 +49,39 @@ class Date extends AbstractRule $this->format = $exceptionalFormats[$this->format]; } - $info = date_parse_from_format($this->format, $inputString); + return $this->isValidForFormatProvided($input); + } + private function isValidForFormatProvided($input) + { + $info = date_parse_from_format($this->format, $input); + if (!$this->isParsable($info)) { + return false; + } + + if ($this->hasDateFormat()) { + return $this->hasValidDate($info); + } + + return true; + } + + private function isParsable(array $info) + { return ($info['error_count'] === 0 && $info['warning_count'] === 0); } + + private function hasDateFormat() + { + return preg_match('/[djSFmMnYy]/', $this->format) > 0; + } + + private function hasValidDate(array $info) + { + if ($info['day']) { + return checkdate((int) $info['month'], $info['day'], (int) $info['year']); + } + + return checkdate($info['month'] ?: 1, $info['day'] ?: 1, $info['year'] ?: 1); + } } diff --git a/tests/unit/Rules/DateTest.php b/tests/unit/Rules/DateTest.php index 0b895592..b0262a6e 100644 --- a/tests/unit/Rules/DateTest.php +++ b/tests/unit/Rules/DateTest.php @@ -19,7 +19,7 @@ use DateTimeImmutable; * @covers Respect\Validation\Rules\Date * @covers Respect\Validation\Exceptions\DateException */ -class DateTest extends \PHPUnit_Framework_TestCase +class DateTest extends RuleTestCase { protected $dateValidator; @@ -150,4 +150,57 @@ class DateTest extends \PHPUnit_Framework_TestCase ['UTC', 'z', 320], ]; } + + /** + * {@inheritdoc} + */ + public function providerForValidInput() + { + return [ + [new Date(), 'now'], + [new Date(), 'today'], + [new Date(), 'tomorrow'], + [new Date(), 'yesterday'], + [new Date(), '+1 day'], + [new Date(), 'next Thursday'], + [new Date(), '+1 week 2 days 4 hours 2 seconds'], + [new Date(), 2018], + [new Date(), new DateTime()], + [new Date('Y-m-d'), '2009-09-09'], + [new Date('d/m/Y'), '23/05/1987'], + [new Date('c'), '2004-02-12T15:19:21+00:00'], + [new Date('r'), 'Thu, 29 Dec 2005 01:02:03 +0000'], + [new Date('U'), 1464658596], + [new Date('h'), 6], + [new Date('z'), 320], + [new Date('Ym'), 202302], + [new Date('m'), 12], + [new Date('Y'), 2000], + ]; + } + + /** + * {@inheritdoc} + */ + public function providerForInvalidInput() + { + return [ + [new Date(), 'not-a-date'], + [new Date(), []], + [new Date(), true], + [new Date(), false], + [new Date(), null], + [new Date(), ''], + [new Date('Y-m-d'), '2009-12-00'], + [new Date('Y-m-d'), '2018-02-29'], + [new Date('h'), 24], + [new Date(), '2014-99'], + [new Date('d'), 1], + [new Date('Y-m'), '2014-99'], + [new Date('m'), '99'], + [new Date('H'), '24'], + [new Date('i'), '60'], + [new Date('s'), '60'], + ]; + } }