1<?php 2 3declare(strict_types=1); 4 5namespace JMS\Serializer\Tests\Handler; 6 7use JMS\Serializer\Handler\DateHandler; 8use JMS\Serializer\JsonDeserializationVisitor; 9use JMS\Serializer\SerializationContext; 10use JMS\Serializer\Visitor\SerializationVisitorInterface; 11use PHPUnit\Framework\TestCase; 12 13class DateHandlerTest extends TestCase 14{ 15 /** 16 * @var DateHandler 17 */ 18 private $handler; 19 /** 20 * @var \DateTimeZone 21 */ 22 private $timezone; 23 24 public function setUp() 25 { 26 $this->handler = new DateHandler(); 27 $this->timezone = new \DateTimeZone('UTC'); 28 } 29 30 public function getParams() 31 { 32 return [ 33 [['Y-m-d']], 34 [['Y-m-d', '', 'Y-m-d|']], 35 [['Y-m-d', '', 'Y']], 36 ]; 37 } 38 39 /** 40 * @param array $params 41 * 42 * @doesNotPerformAssertions 43 * @dataProvider getParams 44 */ 45 public function testSerializeDate(array $params) 46 { 47 $context = $this->getMockBuilder(SerializationContext::class)->getMock(); 48 49 $visitor = $this->getMockBuilder(SerializationVisitorInterface::class)->getMock(); 50 $visitor->method('visitString')->with('2017-06-18'); 51 52 $datetime = new \DateTime('2017-06-18 14:30:59', $this->timezone); 53 $type = ['name' => 'DateTime', 'params' => $params]; 54 $this->handler->serializeDateTime($visitor, $datetime, $type, $context); 55 } 56 57 public function testTimePartGetsRemoved() 58 { 59 $visitor = new JsonDeserializationVisitor(); 60 61 $type = ['name' => 'DateTime', 'params' => ['Y-m-d', '', 'Y-m-d|']]; 62 self::assertEquals( 63 \DateTime::createFromFormat('Y-m-d|', '2017-06-18', $this->timezone), 64 $this->handler->deserializeDateTimeFromJson($visitor, '2017-06-18', $type) 65 ); 66 } 67 68 public function testTimePartGetsPreserved() 69 { 70 $visitor = new JsonDeserializationVisitor(); 71 72 $expectedDateTime = \DateTime::createFromFormat('Y-m-d', '2017-06-18', $this->timezone); 73 // if the test is executed exactly at midnight, it might not detect a possible failure since the time component will be "00:00:00 74 // I know, this is a bit paranoid 75 if ('00:00:00' === $expectedDateTime->format('H:i:s')) { 76 sleep(1); 77 $expectedDateTime = \DateTime::createFromFormat('Y-m-d', '2017-06-18', $this->timezone); 78 } 79 80 // no custom deserialization format specified 81 $type = ['name' => 'DateTime', 'params' => ['Y-m-d']]; 82 self::assertEquals( 83 $expectedDateTime, 84 $this->handler->deserializeDateTimeFromJson($visitor, '2017-06-18', $type) 85 ); 86 87 // custom deserialization format specified 88 $type = ['name' => 'DateTime', 'params' => ['Y-m-d', '', 'Y-m-d']]; 89 self::assertEquals( 90 $expectedDateTime, 91 $this->handler->deserializeDateTimeFromJson($visitor, '2017-06-18', $type) 92 ); 93 } 94 95 public function testTimeZoneGetsPreservedWithUnixTimestamp() 96 { 97 $visitor = new JsonDeserializationVisitor(); 98 99 $timestamp = (string) time(); 100 $timezone = 'Europe/Brussels'; 101 $type = ['name' => 'DateTime', 'params' => ['U', $timezone]]; 102 103 $expectedDateTime = \DateTime::createFromFormat('U', $timestamp); 104 $expectedDateTime->setTimezone(new \DateTimeZone($timezone)); 105 106 $actualDateTime = $this->handler->deserializeDateTimeFromJson($visitor, $timestamp, $type); 107 108 self::assertEquals( 109 $expectedDateTime->format(\DateTime::RFC3339), 110 $actualDateTime->format(\DateTime::RFC3339) 111 ); 112 } 113 114 public function testImmutableTimeZoneGetsPreservedWithUnixTimestamp() 115 { 116 $visitor = new JsonDeserializationVisitor(); 117 118 $timestamp = (string) time(); 119 $timezone = 'Europe/Brussels'; 120 $type = ['name' => 'DateTimeImmutable', 'params' => ['U', $timezone]]; 121 122 $expectedDateTime = \DateTime::createFromFormat('U', $timestamp); 123 $expectedDateTime->setTimezone(new \DateTimeZone($timezone)); 124 125 $actualDateTime = $this->handler->deserializeDateTimeImmutableFromJson($visitor, $timestamp, $type); 126 127 self::assertEquals( 128 $expectedDateTime->format(\DateTime::RFC3339), 129 $actualDateTime->format(\DateTime::RFC3339) 130 ); 131 } 132} 133