8000 [Serializer] Add a new DateTime normalizer · symfony/symfony@6749a70 · GitHub
[go: up one dir, main page]

Skip to content

Commit 6749a70

Browse files
committed
[Serializer] Add a new DateTime normalizer
1 parent caae21c commit 6749a70

File tree

2 files changed

+176
-0
lines changed

2 files changed

+176
-0
lines changed
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Serializer\Normalizer;
13+
14+
use Symfony\Component\Serializer\Exception\InvalidArgumentException;
15+
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
16+
17+
/**
18+
* Normalizes an object implementing the {@see \DateTimeInterface} to a date string.
19+
* Denormalizes a date string to an instance of {@see \DateTime} or {@see \DateTimeImmutable}.
20+
*
21+
* @author Kévin Dunglas <dunglas@gmail.com>
22+
*/
23+
class DateTimeNormalizer implements NormalizerInterface, DenormalizerInterface
24+
{
25+
const FORMAT_KEY = 'datetime_format';
26+
27+
/**
28+
* @var string
29+
*/
30+
private $format;
31+
32+
/**
33+
* @param string $format
34+
*/
35+
public function __construct($format = \DateTime::RFC3339)
36+
{
37+
$this->format = $format;
38+
}
39+
40+
/**
41+
* {@inheritdoc}
42+
*
43+
* @throws InvalidArgumentException
44+
*/
45+
public function normalize($object, $format = null, array $context = array())
46+
{
47+
if (!$object instanceof \DateTimeInterface) {
48+
throw new InvalidArgumentException('The object must implement the "\DateTimeInterface".');
49+
}
50+
51+
$format = isset($context[self::FORMAT_KEY]) ? $context[self::FORMAT_KEY] : $this->format;
52+
53+
return $object->format($format);
54+
}
55+
56+
/**
57+
* {@inheritdoc}
58+
*/
59+
public function supportsNormalization($data, $format = null)
60+
{
61+
return $data instanceof \DateTimeInterface;
62+
}
63+
64+
/**
65+
* {@inheritdoc}
66+
*
67+
* @throws UnexpectedValueException
68+
*/
69+
public function denormalize($data, $class, $format = null, array $context = array())
70+
{
71+
try {
72+
return \DateTime::class === $class ? new \DateTime($data) : new \DateTimeImmutable($data);
73+
} catch (\Exception $e) {
74+
throw new UnexpectedValueException($e->getMessage(), $e->getCode(), $e);
75+
}
76+
}
77+
78+
/**
79+
* {@inheritdoc}
80+
*/
81+
public function supportsDenormalization($data, $type, $format = null)
82+
{
83+
$supportedTypes = array(
84+
\DateTimeInterface::class => true,
85+
\DateTimeImmutable::class => true,
86+
\DateTime::class => true,
87+
);
88+
89+
return isset($supportedTypes[$type]);
90+
}
91+
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Serializer\Tests\Normalizer;
13+
14+
use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;
15+
16+
/**
17+
* @author Kévin Dunglas <dunglas@gmail.com>
18+
*/
19+
class DateTimeNormalizerTest extends \PHPUnit_Framework_TestCase
20+
{
21+
/**
22+
* @var DateTimeNormalizer
23+
*/
24+
private $normalizer;
25+
26+
public function setUp()
27+
{
28+
$this->normalizer = new DateTimeNormalizer();
29+
}
30+
31+
public function testSupportNormalization()
32+
{
33+
$this->assertTrue($this->normalizer->supportsNormalization(new \DateTime()));
34+
$this->assertTrue($this->normalizer->supportsNormalization(new \DateTimeImmutable()));
35+
$this->assertFalse($this->normalizer->supportsNormalization(new \stdClass()));
36+
}
37+
38+
public function testNormalize()
39+
{
40+
$this->assertEquals('2016-01-01T00:00:00+00:00', $this->normalizer->normalize(new \DateTime('2016/01/01')));
41+
$this->assertEquals('2016-01-01T00:00:00+00:00', $this->normalizer->normalize(new \DateTimeImmutable('2016/01/01')));
42+
}
43+
44+
public function testContextFormat()
45+
{
46+
$this->assertEquals('2016', $this->normalizer->normalize(new \DateTime('2016/01/01'), null, array(DateTimeNormalizer::FORMAT_KEY => 'Y')));
47+
}
48+
49+
public function testConstructorFormat()
50+
{
51+
$this->assertEquals('16', (new DateTimeNormalizer('y'))->normalize(new \DateTime('2016/01/01')));
52+
}
53+
54+
/**
55+
* @expectedException \Symfony\Component\Serializer\Exception\InvalidArgumentException
56+
* @expectedExceptionMessage The object must implement the "\DateTimeInterface".
57+
*/
58+
public function testInvalidDataThrowException()
59+
{
60+
$this->normalizer->normalize(new \stdClass());
61+
}
62+
63+
public function testSupportDenormalization()
64+
{
65+
$this->assertTrue($this->normalizer->supportsDenormalization('2016-01-01T00:00:00+00:00', \DateTimeInterface::class));
66+
$this->assertTrue($this->normalizer->supportsDenormalization('2016-01-01T00:00:00+00:00', \DateTime::class));
67+
$this->assertTrue($this->normalizer->supportsDenormalization('2016-01-01T00:00:00+00:00', \DateTimeImmutable::class));
68+
$this->assertFalse($this->normalizer->supportsDenormalization('foo', 'Bar'));
69+
}
70+
71+
public function testDenormalize()
72+
{
73+
$this->assertEquals(new \DateTimeImmutable('2016/01/01'), $this->normalizer->denormalize('2016-01-01T00:00:00+00:00', \DateTimeInterface::class));
74+
$this->assertEquals(new \DateTimeImmutable('2016/01/01'), $this->normalizer->denormalize('2016-01-01T00:00:00+00:00', \DateTimeImmutable::class));
75+
$this->assertEquals(new \DateTime('2016/01/01'), $this->normalizer->denormalize('2016-01-01T00:00:00+00:00', \DateTime::class));
76+
}
77+
78+
/**
79+
* @expectedException \Symfony\Component\Serializer\Exception\UnexpectedValueException
80+
*/
81+
public function testInvalidDateThrowException()
82+
{
83+
$this->normalizer->denormalize('invalid date', \DateTimeInterface::class);
84+
}
3516 85+
}

0 commit comments

Comments
 (0)
0