4 * This file is part of the Symfony package.
6 * (c) Fabien Potencier <fabien@symfony.com>
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
12 namespace Symfony\Component\Serializer\Tests\Normalizer;
14 use PHPUnit\Framework\TestCase;
15 use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;
18 * @author Kévin Dunglas <dunglas@gmail.com>
20 class DateTimeNormalizerTest extends TestCase
23 * @var DateTimeNormalizer
27 protected function setUp()
29 $this->normalizer = new DateTimeNormalizer();
32 public function testSupportsNormalization()
34 $this->assertTrue($this->normalizer->supportsNormalization(new \DateTime()));
35 $this->assertTrue($this->normalizer->supportsNormalization(new \DateTimeImmutable()));
36 $this->assertFalse($this->normalizer->supportsNormalization(new \stdClass()));
39 public function testNormalize()
41 $this->assertEquals('2016-01-01T00:00:00+00:00', $this->normalizer->normalize(new \DateTime('2016/01/01', new \DateTimeZone('UTC'))));
42 $this->assertEquals('2016-01-01T00:00:00+00:00', $this->normalizer->normalize(new \DateTimeImmutable('2016/01/01', new \DateTimeZone('UTC'))));
45 public function testNormalizeUsingFormatPassedInContext()
47 $this->assertEquals('2016', $this->normalizer->normalize(new \DateTime('2016/01/01'), null, array(DateTimeNormalizer::FORMAT_KEY => 'Y')));
50 public function testNormalizeUsingFormatPassedInConstructor()
52 $this->assertEquals('16', (new DateTimeNormalizer('y'))->normalize(new \DateTime('2016/01/01', new \DateTimeZone('UTC'))));
55 public function testNormalizeUsingTimeZonePassedInConstructor()
57 $normalizer = new DateTimeNormalizer(\DateTime::RFC3339, new \DateTimeZone('Japan'));
59 $this->assertSame('2016-12-01T00:00:00+09:00', $normalizer->normalize(new \DateTime('2016/12/01', new \DateTimeZone('Japan'))));
60 $this->assertSame('2016-12-01T09:00:00+09:00', $normalizer->normalize(new \DateTime('2016/12/01', new \DateTimeZone('UTC'))));
64 * @dataProvider normalizeUsingTimeZonePassedInContextProvider
66 public function testNormalizeUsingTimeZonePassedInContext($expected, $input, $timezone)
68 $this->assertSame($expected, $this->normalizer->normalize($input, null, array(
69 DateTimeNormalizer::TIMEZONE_KEY => $timezone,
73 public function normalizeUsingTimeZonePassedInContextProvider()
75 yield array('2016-12-01T00:00:00+00:00', new \DateTime('2016/12/01', new \DateTimeZone('UTC')), null);
76 yield array('2016-12-01T00:00:00+09:00', new \DateTime('2016/12/01', new \DateTimeZone('Japan')), new \DateTimeZone('Japan'));
77 yield array('2016-12-01T09:00:00+09:00', new \DateTime('2016/12/01', new \DateTimeZone('UTC')), new \DateTimeZone('Japan'));
78 yield array('2016-12-01T09:00:00+09:00', new \DateTimeImmutable('2016/12/01', new \DateTimeZone('UTC')), new \DateTimeZone('Japan'));
82 * @expectedException \Symfony\Component\Serializer\Exception\InvalidArgumentException
83 * @expectedExceptionMessage The object must implement the "\DateTimeInterface".
85 public function testNormalizeInvalidObjectThrowsException()
87 $this->normalizer->normalize(new \stdClass());
90 public function testSupportsDenormalization()
92 $this->assertTrue($this->normalizer->supportsDenormalization('2016-01-01T00:00:00+00:00', \DateTimeInterface::class));
93 $this->assertTrue($this->normalizer->supportsDenormalization('2016-01-01T00:00:00+00:00', \DateTime::class));
94 $this->assertTrue($this->normalizer->supportsDenormalization('2016-01-01T00:00:00+00:00', \DateTimeImmutable::class));
95 $this->assertFalse($this->normalizer->supportsDenormalization('foo', 'Bar'));
98 public function testDenormalize()
100 $this->assertEquals(new \DateTimeImmutable('2016/01/01', new \DateTimeZone('UTC')), $this->normalizer->denormalize('2016-01-01T00:00:00+00:00', \DateTimeInterface::class));
101 $this->assertEquals(new \DateTimeImmutable('2016/01/01', new \DateTimeZone('UTC')), $this->normalizer->denormalize('2016-01-01T00:00:00+00:00', \DateTimeImmutable::class));
102 $this->assertEquals(new \DateTime('2016/01/01', new \DateTimeZone('UTC')), $this->normalizer->denormalize('2016-01-01T00:00:00+00:00', \DateTime::class));
105 public function testDenormalizeUsingTimezonePassedInConstructor()
107 $timezone = new \DateTimeZone('Japan');
108 $expected = new \DateTime('2016/12/01 17:35:00', $timezone);
109 $normalizer = new DateTimeNormalizer(null, $timezone);
111 $this->assertEquals($expected, $normalizer->denormalize('2016.12.01 17:35:00', \DateTime::class, null, array(
112 DateTimeNormalizer::FORMAT_KEY => 'Y.m.d H:i:s',
116 public function testDenormalizeUsingFormatPassedInContext()
118 $this->assertEquals(new \DateTimeImmutable('2016/01/01'), $this->normalizer->denormalize('2016.01.01', \DateTimeInterface::class, null, array(DateTimeNormalizer::FORMAT_KEY => 'Y.m.d|')));
119 $this->assertEquals(new \DateTimeImmutable('2016/01/01'), $this->normalizer->denormalize('2016.01.01', \DateTimeImmutable::class, null, array(DateTimeNormalizer::FORMAT_KEY => 'Y.m.d|')));
120 $this->assertEquals(new \DateTime('2016/01/01'), $this->normalizer->denormalize('2016.01.01', \DateTime::class, null, array(DateTimeNormalizer::FORMAT_KEY => 'Y.m.d|')));
124 * @dataProvider denormalizeUsingTimezonePassedInContextProvider
126 public function testDenormalizeUsingTimezonePassedInContext($input, $expected, $timezone, $format = null)
128 $actual = $this->normalizer->denormalize($input, \DateTimeInterface::class, null, array(
129 DateTimeNormalizer::TIMEZONE_KEY => $timezone,
130 DateTimeNormalizer::FORMAT_KEY => $format,
133 $this->assertEquals($expected, $actual);
136 public function denormalizeUsingTimezonePassedInContextProvider()
138 yield 'with timezone' => array(
139 '2016/12/01 17:35:00',
140 new \DateTimeImmutable('2016/12/01 17:35:00', new \DateTimeZone('Japan')),
141 new \DateTimeZone('Japan'),
143 yield 'with timezone as string' => array(
144 '2016/12/01 17:35:00',
145 new \DateTimeImmutable('2016/12/01 17:35:00', new \DateTimeZone('Japan')),
148 yield 'with format without timezone information' => array(
149 '2016.12.01 17:35:00',
150 new \DateTimeImmutable('2016/12/01 17:35:00', new \DateTimeZone('Japan')),
151 new \DateTimeZone('Japan'),
154 yield 'ignored with format with timezone information' => array(
155 '2016-12-01T17:35:00Z',
156 new \DateTimeImmutable('2016/12/01 17:35:00', new \DateTimeZone('UTC')),
163 * @expectedException \Symfony\Component\Serializer\Exception\UnexpectedValueException
165 public function testDenormalizeInvalidDataThrowsException()
167 $this->normalizer->denormalize('invalid date', \DateTimeInterface::class);
171 * @expectedException \Symfony\Component\Serializer\Exception\UnexpectedValueException
172 * @expectedExceptionMessage The data is either an empty string or null, you should pass a string that can be parsed with the passed format or a valid DateTime string.
174 public function testDenormalizeNullThrowsException()
176 $this->normalizer->denormalize(null, \DateTimeInterface::class);
180 * @expectedException \Symfony\Component\Serializer\Exception\UnexpectedValueException
181 * @expectedExceptionMessage The data is either an empty string or null, you should pass a string that can be parsed with the passed format or a valid DateTime string.
183 public function testDenormalizeEmptyStringThrowsException()
185 $this->normalizer->denormalize('', \DateTimeInterface::class);
189 * @expectedException \Symfony\Component\Serializer\Exception\UnexpectedValueException
191 public function testDenormalizeFormatMismatchThrowsException()
193 $this->normalizer->denormalize('2016-01-01T00:00:00+00:00', \DateTimeInterface::class, null, array(DateTimeNormalizer::FORMAT_KEY => 'Y-m-d|'));