diff --git a/doc/reference/annotations.rst b/doc/reference/annotations.rst index 6fc0cb9f7..1094db672 100644 --- a/doc/reference/annotations.rst +++ b/doc/reference/annotations.rst @@ -350,28 +350,27 @@ Available Types: +------------------------------------------------------------+--------------------------------------------------+ | DateTime | PHP's DateTime object (default format*/timezone) | +------------------------------------------------------------+--------------------------------------------------+ -| DateTime<'formats'> | PHP's DateTime object (custom format/default | -| | timezone). Formats can either be a string or an | -| | array of string. | +| DateTime<'format'> | PHP's DateTime object (custom format/default | +| | timezone). | +------------------------------------------------------------+--------------------------------------------------+ -| DateTime<'formats', 'zone'> | PHP's DateTime object (custom format/timezone) | +| DateTime<'format', 'zone'> | PHP's DateTime object (custom format/timezone) | +------------------------------------------------------------+--------------------------------------------------+ -| DateTime<'formats', 'zone', 'deserializeFormats'> | PHP's DateTime object (custom format/timezone, | +| DateTime<'format', 'zone', 'deserializeFormats'> | PHP's DateTime object (custom format/timezone, | | | deserialize format). If you do not want to | | | specify a specific timezone, use an empty | -| | string (''). | +| | string (''). DeserializeFormats can either be a | +| | string or an array of string. | +------------------------------------------------------------+--------------------------------------------------+ | DateTimeImmutable | PHP's DateTimeImmutable object (default format*/ | -| | timezone). Formats can either be a string or an | -| | array of string. | +| | timezone). | +------------------------------------------------------------+--------------------------------------------------+ -| DateTimeImmutable<'formats'> | PHP's DateTimeImmutable object (custom format/ | +| DateTimeImmutable<'format'> | PHP's DateTimeImmutable object (custom format/ | | | default timezone) | +------------------------------------------------------------+--------------------------------------------------+ -| DateTimeImmutable<'formats', 'zone'> | PHP's DateTimeImmutable object (custom format/ | +| DateTimeImmutable<'format', 'zone'> | PHP's DateTimeImmutable object (custom format/ | | | timezone) | +------------------------------------------------------------+--------------------------------------------------+ -| DateTimeImmutable<'formats', 'zone', 'deserializeFormats'> | PHP's DateTimeImmutable object (custom format/ | +| DateTimeImmutable<'format', 'zone', 'deserializeFormats'> | PHP's DateTimeImmutable object (custom format/ | | | timezone/deserialize format). If you do not want | | | to specify a specific timezone, use an empty | | | string (''). DeserializeFormats can either be a | @@ -467,7 +466,7 @@ Examples: private $endAt; /** - * @Type("DateTime<['Y-m-d', 'Y/m/d']>") + * @Type("DateTime<'Y-m-d', '', ['Y-m-d', 'Y/m/d']>") */ private $publishedAt; @@ -482,7 +481,7 @@ Examples: private $updatedAt; /** - * @Type("DateTimeImmutable<['Y-m-d', 'Y/m/d']>") + * @Type("DateTimeImmutable<'Y-m-d', '', ['Y-m-d', 'Y/m/d']>") */ private $deletedAt; diff --git a/src/Handler/DateHandler.php b/src/Handler/DateHandler.php index a271bee56..a004dc15b 100644 --- a/src/Handler/DateHandler.php +++ b/src/Handler/DateHandler.php @@ -75,25 +75,16 @@ private function serializeDateTimeInterface( array $type, SerializationContext $context ) { - $formats = $this->getFormats($type); - - foreach ($formats as $format) { - $dateFormatted = $date->format($format); - - if (false !== $dateFormatted) { - if ($visitor instanceof XmlSerializationVisitor && false === $this->xmlCData) { - return $visitor->visitSimpleString($dateFormatted, $type); - } - - if ('U' === $format) { - return $visitor->visitInteger((int) $dateFormatted, $type); - } + if ($visitor instanceof XmlSerializationVisitor && false === $this->xmlCData) { + return $visitor->visitSimpleString($date->format($this->getFormat($type)), $type); + } - return $visitor->visitString($dateFormatted, $type); - } + $format = $this->getFormat($type); + if ('U' === $format) { + return $visitor->visitInteger((int) $date->format($format), $type); } - throw new RuntimeException(sprintf('The date "%s" could not be formatted', $date)); + return $visitor->visitString($date->format($this->getFormat($type)), $type); } /** @@ -278,21 +269,16 @@ private function getDeserializationFormats(array $type): array if (isset($type['params'][2])) { return is_array($type['params'][2]) ? $type['params'][2] : [$type['params'][2]]; } - if (isset($type['params'][0])) { - return is_array($type['params'][0]) ? $type['params'][0] : [$type['params'][0]]; - } - return [$this->defaultFormat]; + + return [$this->getFormat($type)]; } /** * @param array $type */ - private function getFormats(array $type): array + private function getFormat(array $type): string { - if (isset($type['params'][0])) { - return is_array($type['params'][0]) ? $type['params'][0] : [$type['params'][0]]; - } - return [$this->defaultFormat]; + return $type['params'][0] ?? $this->defaultFormat; } public function format(\DateInterval $dateInterval): string diff --git a/tests/Handler/DateHandlerTest.php b/tests/Handler/DateHandlerTest.php index 17b69bd16..881c664d2 100644 --- a/tests/Handler/DateHandlerTest.php +++ b/tests/Handler/DateHandlerTest.php @@ -33,7 +33,7 @@ public function getParams() [['Y-m-d']], [['Y-m-d', '', 'Y-m-d|']], [['Y-m-d', '', 'Y']], - [[['Y-m-d', 'Y/m/d'], '', 'Y']], + [['Y-m-d', '', ['Y-m-d', 'Y/m/d']]], ]; } diff --git a/tests/Serializer/BaseSerializationTest.php b/tests/Serializer/BaseSerializationTest.php index dc02723a6..a343e8b75 100644 --- a/tests/Serializer/BaseSerializationTest.php +++ b/tests/Serializer/BaseSerializationTest.php @@ -665,6 +665,7 @@ public function getDateTime() { return [ ['date_time', new \DateTime('2011-08-30 00:00', new \DateTimeZone('UTC')), 'DateTime'], + ['date_time_multi_format', new \DateTime('2011-08-30 00:00', new \DateTimeZone('UTC')), "DateTime<'Y-m-d', '', ['Y-m-d','Y-m-d\TH:i:sP']>"], ]; } diff --git a/tests/Serializer/JsonSerializationTest.php b/tests/Serializer/JsonSerializationTest.php index 471d5e378..09f88ddfe 100644 --- a/tests/Serializer/JsonSerializationTest.php +++ b/tests/Serializer/JsonSerializationTest.php @@ -93,6 +93,7 @@ protected function getContent($key) $outputs['object_when_null_and_serialized'] = '{"author":null,"text":"foo"}'; $outputs['date_time'] = '"2011-08-30T00:00:00+00:00"'; $outputs['date_time_immutable'] = '"2011-08-30T00:00:00+00:00"'; + $outputs['date_time_multi_format'] = '"2011-08-30T00:00:00+00:00"'; $outputs['timestamp'] = '{"timestamp":1455148800}'; $outputs['timestamp_prev'] = '{"timestamp":"1455148800"}'; $outputs['date_interval'] = '"PT45M"'; diff --git a/tests/Serializer/xml/date_time_multi_format.xml b/tests/Serializer/xml/date_time_multi_format.xml new file mode 100644 index 000000000..5d0767627 --- /dev/null +++ b/tests/Serializer/xml/date_time_multi_format.xml @@ -0,0 +1,2 @@ + + diff --git a/tests/Serializer/xml/date_time_multi_format_no_cdata.xml b/tests/Serializer/xml/date_time_multi_format_no_cdata.xml new file mode 100644 index 000000000..d596a0f83 --- /dev/null +++ b/tests/Serializer/xml/date_time_multi_format_no_cdata.xml @@ -0,0 +1,2 @@ + +2011-08-30T00:00:00+00:00