diff --git a/CHANGELOG.md b/CHANGELOG.md index e918fb94..185954a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ Latest * [#192](https://github.com/cleverage/process-bundle/issues/192) Fix CommandRunnerTask: only pass the `options` option to `Process::setOptions()`, support string `commandline` through `Process::fromShellCommandline()`, validate option types. Update documentation, add tests. * [#194](https://github.com/cleverage/process-bundle/issues/194) Fix ProcessLauncherTask: the `process_options` normalizer returned an array despite its scalar return type, so the task always failed with a `TypeError`. Update documentation, add tests. * [#189](https://github.com/cleverage/process-bundle/issues/189) Fix EventDispatcherTask: dispatch the event under the `event_name` option (regression since v4.0). `event_name` is now optional: when `null` (default), the event is dispatched under its class name. Update documentation, add tests. +* [#198](https://github.com/cleverage/process-bundle/issues/198) Fix DateParserTransformer: a `\DateTimeImmutable` input is converted to a `\DateTime` instead of throwing a `TypeError`. Update documentation, add tests. ## Deprecated * [#189](https://github.com/cleverage/process-bundle/issues/189) EventDispatcherTask: when `event_name` is set, listening to `CleverAge\ProcessBundle\Event\EventDispatcherTaskEvent` is deprecated (the event is still dispatched under its class name, with an `E_USER_DEPRECATED` error, if it has listeners). Listen to the configured `event_name` instead: the BC layer will be removed in v6.0. diff --git a/docs/reference/transformers/date_parser_transformer.md b/docs/reference/transformers/date_parser_transformer.md index fd584bb6..6163b639 100644 --- a/docs/reference/transformers/date_parser_transformer.md +++ b/docs/reference/transformers/date_parser_transformer.md @@ -14,6 +14,7 @@ Accepted inputs * `string`: a date matching the configured `format` * `\DateTime`, returned unchanged +* `\DateTimeImmutable`, converted to a `\DateTime` (same date, time and timezone) * Any falsy value (`null`, `''`, `false`…), returned unchanged A string that cannot be parsed with the given format throws an `\UnexpectedValueException`. @@ -55,5 +56,3 @@ Notes Fields missing from `format` are taken from the current time (e.g. with `Y-m-d`, the time part is the current time). Use the `!` or `|` format characters to reset them, e.g. `'!Y-m-d'`. - -A `\DateTimeImmutable` input is not returned unchanged: it is passed to `createFromFormat()` and throws a `\TypeError`. diff --git a/src/Transformer/Date/DateParserTransformer.php b/src/Transformer/Date/DateParserTransformer.php index a891ff40..526d0afd 100644 --- a/src/Transformer/Date/DateParserTransformer.php +++ b/src/Transformer/Date/DateParserTransformer.php @@ -17,7 +17,7 @@ use Symfony\Component\OptionsResolver\OptionsResolver; /** - * Transformer aiming to take a date as an input (object or a format defined string) to strictly output aa \DateTime. + * Transformer aiming to take a date as an input (object or a format defined string) to strictly output a \DateTime. * * @example in YML config * transformers: @@ -32,6 +32,10 @@ public function transform(mixed $value, array $options = []): mixed return $value; } + if ($value instanceof \DateTimeImmutable) { + return \DateTime::createFromImmutable($value); + } + $date = \DateTime::createFromFormat($options['format'], $value); if (!$date) { diff --git a/tests/Transformer/Date/DateParserTransformerTest.php b/tests/Transformer/Date/DateParserTransformerTest.php index 5cb330f7..e07dab2b 100644 --- a/tests/Transformer/Date/DateParserTransformerTest.php +++ b/tests/Transformer/Date/DateParserTransformerTest.php @@ -69,6 +69,19 @@ public function testTransformDateTimeObject(): void $this->assertSame($value, $transformedValue); } + public function testTransformDateTimeImmutableObject(): void + { + $transformer = new DateParserTransformer(); + $value = new \DateTimeImmutable('2023-09-28 12:34:56', new \DateTimeZone('Europe/Paris')); + $options = ['format' => 'Y-m-d']; + + $transformedValue = $transformer->transform($value, $options); + + $this->assertInstanceOf(\DateTime::class, $transformedValue); + $this->assertEquals($value, \DateTimeImmutable::createFromMutable($transformedValue)); + $this->assertSame('Europe/Paris', $transformedValue->getTimezone()->getName()); + } + public function testGetCode(): void { $transformer = new DateParserTransformer();