Skip to content

Commit

Permalink
added support for milliseconds in DateInterval deserialization
Browse files Browse the repository at this point in the history
  • Loading branch information
ivoba committed Jul 10, 2020
1 parent 88be308 commit 5e1c7ae
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 0 deletions.
9 changes: 9 additions & 0 deletions src/Handler/DateHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,16 @@ private function parseDateInterval(string $data): \DateInterval
{
$dateInterval = null;
try {
$f = 0.0;
if (preg_match('~\.\d+~', $data, $match)) {
$data = str_replace($match[0], '', $data);
$f = (float) $match[0];
}
$dateInterval = new \DateInterval($data);
// milliseconds are only available from >=7.1
if (isset($dateInterval->f)) {
$dateInterval->f= $f;
}
} catch (\Throwable $e) {
throw new RuntimeException(sprintf('Invalid dateinterval "%s", expected ISO 8601 format', $data), 0, $e);
}
Expand Down
30 changes: 30 additions & 0 deletions tests/Handler/DateHandlerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use JMS\Serializer\Handler\DateHandler;
use JMS\Serializer\JsonDeserializationVisitor;
use JMS\Serializer\SerializationContext;
use JMS\Serializer\Visitor\DeserializationVisitorInterface;
use JMS\Serializer\Visitor\SerializationVisitorInterface;
use PHPUnit\Framework\TestCase;

Expand Down Expand Up @@ -55,6 +56,35 @@ public function testSerializeDate(array $params)
$this->handler->serializeDateTime($visitor, $datetime, $type, $context);
}

/**
* @param string $dateInterval
* @param \DateTime $expected
*
* @dataProvider getDeserializeDateInterval
*/
public function testDeserializeDateInterval($dateInterval, $expected)
{
$context = $this->getMockBuilder(SerializationContext::class)->getMock();

$visitor = $this->getMockBuilder(DeserializationVisitorInterface::class)->getMock();
$visitor->method('visitString')->with('2017-06-18');

$element = new \SimpleXMLElement('<DateInterval>'.$dateInterval.'</DateInterval>');
$deserialized = $this->handler->deserializeDateIntervalFromXml($visitor, $element, [], $context);
if (isset($deserialized->f)) {
$this->assertEquals($expected['f'], $deserialized->f);
}
$this->assertEquals($expected['s'], $deserialized->s);
}

public function getDeserializeDateInterval()
{
return [
['P0Y0M0DT3H5M7.520S', ['s' => 7, 'f' => 0.52]],
['P0Y0M0DT3H5M7S', ['s' => 7, 'f' => 0]],
];
}

public function testTimePartGetsRemoved()
{
$visitor = new JsonDeserializationVisitor();
Expand Down

0 comments on commit 5e1c7ae

Please sign in to comment.