From cdb11a7ec988ff1fa0652a993b0fb8e547a005ee Mon Sep 17 00:00:00 2001 From: Noah Heck Date: Thu, 17 Nov 2016 08:00:37 -0700 Subject: [PATCH] [YAML] Fix processing timestamp with timezone Parse date strings containing timezone data correctly Default date strings not containing timezone data to UTC --- src/Symfony/Component/Yaml/Inline.php | 6 ++---- .../Component/Yaml/Tests/InlineTest.php | 20 ++++++++++++------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/Symfony/Component/Yaml/Inline.php b/src/Symfony/Component/Yaml/Inline.php index 9169c592b8639..a8acf0a2afbbb 100644 --- a/src/Symfony/Component/Yaml/Inline.php +++ b/src/Symfony/Component/Yaml/Inline.php @@ -606,10 +606,8 @@ private static function evaluateScalar($scalar, $flags, $references = array()) return (float) str_replace(',', '', $scalar); case preg_match(self::getTimestampRegex(), $scalar): if (Yaml::PARSE_DATETIME & $flags) { - $date = new \DateTime($scalar); - $date->setTimeZone(new \DateTimeZone('UTC')); - - return $date; + // When no timezone is provided in the parsed date, YAML spec says we must assume UTC. + return new \DateTime($scalar, new \DateTimeZone('UTC')); } $timeZone = date_default_timezone_get(); diff --git a/src/Symfony/Component/Yaml/Tests/InlineTest.php b/src/Symfony/Component/Yaml/Tests/InlineTest.php index 83d20cc96c82a..bbafadb774a33 100644 --- a/src/Symfony/Component/Yaml/Tests/InlineTest.php +++ b/src/Symfony/Component/Yaml/Tests/InlineTest.php @@ -502,7 +502,7 @@ public function testParseTimestampAsUnixTimestampByDefault($yaml, $year, $month, /** * @dataProvider getTimestampTests */ - public function testParseTimestampAsDateTimeObject($yaml, $year, $month, $day, $hour, $minute, $second) + public function testParseTimestampAsDateTimeObject($yaml, $year, $month, $day, $hour, $minute, $second, $timezone) { $expected = new \DateTime($yaml); $expected->setTimeZone(new \DateTimeZone('UTC')); @@ -514,16 +514,18 @@ public function testParseTimestampAsDateTimeObject($yaml, $year, $month, $day, $ $expected->setTime($hour, $minute, $second); } - $this->assertEquals($expected, Inline::parse($yaml, Yaml::PARSE_DATETIME)); + $date = Inline::parse($yaml, Yaml::PARSE_DATETIME); + $this->assertEquals($expected, $date); + $this->assertSame($timezone, $date->format('O')); } public function getTimestampTests() { return array( - 'canonical' => array('2001-12-15T02:59:43.1Z', 2001, 12, 15, 2, 59, 43.1), - 'ISO-8601' => array('2001-12-15t21:59:43.10-05:00', 2001, 12, 16, 2, 59, 43.1), - 'spaced' => array('2001-12-15 21:59:43.10 -5', 2001, 12, 16, 2, 59, 43.1), - 'date' => array('2001-12-15', 2001, 12, 15, 0, 0, 0), + 'canonical' => array('2001-12-15T02:59:43.1Z', 2001, 12, 15, 2, 59, 43.1, '+0000'), + 'ISO-8601' => array('2001-12-15t21:59:43.10-05:00', 2001, 12, 16, 2, 59, 43.1, '-0500'), + 'spaced' => array('2001-12-15 21:59:43.10 -5', 2001, 12, 16, 2, 59, 43.1, '-0500'), + 'date' => array('2001-12-15', 2001, 12, 15, 0, 0, 0, '+0000'), ); } @@ -535,7 +537,11 @@ public function testParseNestedTimestampListAsDateTimeObject($yaml, $year, $mont $expected = new \DateTime($yaml); $expected->setTimeZone(new \DateTimeZone('UTC')); $expected->setDate($year, $month, $day); - @$expected->setTime($hour, $minute, $second, 1000000 * ($second - (int) $second)); + if (PHP_VERSION_ID >= 70100) { + $expected->setTime($hour, $minute, $second, 1000000 * ($second - (int) $second)); + } else { + $expected->setTime($hour, $minute, $second); + } $expectedNested = array('nested' => array($expected)); $yamlNested = "{nested: [$yaml]}";