From b9ddba576034700112334db689970f974eb7768a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Burnichon?= Date: Thu, 3 Mar 2016 13:24:40 +0100 Subject: [PATCH 1/2] Add Rfc339 utility class to create instances of DateTime --- src/JsonSchema/Rfc3339.php | 29 +++++++++++++ tests/JsonSchema/Tests/Rfc3339Test.php | 59 ++++++++++++++++++++++++++ 2 files changed, 88 insertions(+) create mode 100644 src/JsonSchema/Rfc3339.php create mode 100644 tests/JsonSchema/Tests/Rfc3339Test.php diff --git a/src/JsonSchema/Rfc3339.php b/src/JsonSchema/Rfc3339.php new file mode 100644 index 00000000..5afdaed4 --- /dev/null +++ b/src/JsonSchema/Rfc3339.php @@ -0,0 +1,29 @@ +assertInstanceOf('DateTime', $actual); + $this->assertEquals($expected->format('U.u'), $actual->format('U.u')); + } + + /** + * @param string $string + * @dataProvider provideInvalidFormats + */ + public function testCreateFromInvalidString($string) + { + $this->assertNull(Rfc3339::createFromString($string), sprintf('String "%s" should not be converted to DateTime', $string)); + } + + public function provideValidFormats() + { + return array( + array( + '2000-05-01T12:12:12Z', + \DateTime::createFromFormat('Y-m-d\TH:i:s', '2000-05-01T12:12:12', new \DateTimeZone('UTC')) + ), + array('2000-05-01T12:12:12+0100', \DateTime::createFromFormat('Y-m-d\TH:i:sP', '2000-05-01T12:12:12+01:00')), + array('2000-05-01T12:12:12+01:00', \DateTime::createFromFormat('Y-m-d\TH:i:sP', '2000-05-01T12:12:12+01:00')), + array( + '2000-05-01T12:12:12.123456Z', + \DateTime::createFromFormat('Y-m-d\TH:i:s.u', '2000-05-01T12:12:12.123456', new \DateTimeZone('UTC')) + ), + array( + '2000-05-01T12:12:12.123Z', + \DateTime::createFromFormat('Y-m-d\TH:i:s.u', '2000-05-01T12:12:12.123000', new \DateTimeZone('UTC')) + ), + ); + } + + public function provideInvalidFormats() + { + return array( + array('1999-1-11T00:00:00Z'), + array('1999-01-11T00:00:00+100'), + array('1999-01-11T00:00:00+1:00'), + ); + } +} From 6474265bdadc811a3f7e15e200f4b59b4b2d408a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Burnichon?= Date: Thu, 3 Mar 2016 13:30:26 +0100 Subject: [PATCH 2/2] Simplify FormatConstraint using helper class --- .../Constraints/FormatConstraint.php | 21 +++---------------- 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/src/JsonSchema/Constraints/FormatConstraint.php b/src/JsonSchema/Constraints/FormatConstraint.php index c7897538..12c6a2bf 100644 --- a/src/JsonSchema/Constraints/FormatConstraint.php +++ b/src/JsonSchema/Constraints/FormatConstraint.php @@ -8,6 +8,7 @@ */ namespace JsonSchema\Constraints; +use JsonSchema\Rfc3339; /** * Validates against the "format" property @@ -40,11 +41,7 @@ public function check($element, $schema = null, $path = null, $i = null) break; case 'date-time': - if (!$this->validateDateTime($element, 'Y-m-d\TH:i:s\Z') && - !$this->validateDateTime($element, 'Y-m-d\TH:i:s.u\Z') && - !$this->validateDateTime($element, 'Y-m-d\TH:i:sP') && - !$this->validateDateTime($element, 'Y-m-d\TH:i:sO') - ) { + if (null === Rfc3339::createFromString($element)) { $this->addError($path, sprintf('Invalid date-time %s, expected format YYYY-MM-DDThh:mm:ssZ or YYYY-MM-DDThh:mm:ss+hh:mm', json_encode($element)), 'format', array('format' => $schema->format,)); } break; @@ -130,19 +127,7 @@ protected function validateDateTime($datetime, $format) return false; } - if ($datetime === $dt->format($format)) { - return true; - } - - // handles the case where a non-6 digit microsecond datetime is passed - // which will fail the above string comparison because the passed - // $datetime may be '2000-05-01T12:12:12.123Z' but format() will return - // '2000-05-01T12:12:12.123000Z' - if ((strpos('u', $format) !== -1) && (intval($dt->format('u')) > 0)) { - return true; - } - - return false; + return $datetime === $dt->format($format); } protected function validateRegex($regex)