Repository: symfony/symfony
File: src/Symfony/Component/Serializer/Normalizer/DateTimeNormalizer.php (PHP)

Code before:
        try {
            if (\DateTimeInterface::class === $type) {
                $type = \DateTimeImmutable::class;
            }

            $timezone = $this->getTimezone($context);
            $dateTimeFormat = $context[self::FORMAT_KEY] ?? null;

            if (null !== $dateTimeFormat) {
                if (false !== $object = $type::createFromFormat($dateTimeFormat, $data, $timezone)) {
                    return $object;
                }

                $dateTimeErrors = $type::getLastErrors();

                throw NotNormalizableValueException::createForUnexpectedDataType(\sprintf('Parsing datetime string "%s" using format "%s" resulted in %d errors: ', $data, $dateTimeFormat, $dateTimeErrors['error_count'])."\n".implode("\n", $this->formatDateTimeErrors($dateTimeErrors['errors'])), $data, ['string'], $context['deserialization_path'] ?? null, true);
            }

            $defaultDateTimeFormat = $this->defaultContext[self::FORMAT_KEY] ?? null;

            if (null !== $defaultDateTimeFormat) {
                if (false !== $object = $type::createFromFormat($defaultDateTimeFormat, $data, $timezone)) {
                    return $object;
                }

                trigger_deprecation('symfony/serializer', '7.3', \sprintf('A "%s" will be thrown when a date could not be parsed using the default format "%s".', NotNormalizableValueException::class, $defaultDateTimeFormat));
            }

            return new $type($data, $timezone);
        } catch (NotNormalizableValueException $e) {
            throw $e;
        } catch (\Exception $e) {
            throw NotNormalizableValueException::createForUnexpectedDataType($e->getMessage(), $data, ['string'], $context['deserialization_path'] ?? null, false, $e->getCode(), $e);
        }
    }

    public function supportsDenormalization(mixed $data, string $type, ?string $format = null, array $context = []): bool
    {
        return is_a($type, \DateTimeInterface::class, true);
    }

    /**
     * Formats datetime errors.
     *
     * @return string[]
     */
    private function formatDateTimeErrors(array $errors): array
    {
        $formattedErrors = [];

        foreach ($errors as $pos => $message) {

Review comment (suggestion):
I think we should trigger a deprecation here only if the fallback manages to instantiate it. The case where the fallback throws an exception (already turned into a NotNormalizableValueException below) should not trigger a deprecation.

Code after:
        }

        try {
            if (\DateTimeInterface::class === $type) {
                $type = \DateTimeImmutable::class;
            }

            $timezone = $this->getTimezone($context);
            $dateTimeFormat = $context[self::FORMAT_KEY] ?? null;

            if (null !== $dateTimeFormat) {
                if (false !== $object = $type::createFromFormat($dateTimeFormat, $data, $timezone)) {
                    return $this->enforceTimezone($object, $context);
                }

                $dateTimeErrors = $type::getLastErrors();

                throw NotNormalizableValueException::createForUnexpectedDataType(\sprintf('Parsing datetime string "%s" using format "%s" resulted in %d errors: ', $data, $dateTimeFormat, $dateTimeErrors['error_count'])."\n".implode("\n", $this->formatDateTimeErrors($dateTimeErrors['errors'])), $data, ['string'], $context['deserialization_path'] ?? null, true);
            }

            $defaultDateTimeFormat = $this->defaultContext[self::FORMAT_KEY] ?? null;

            if (null !== $defaultDateTimeFormat) {
                if (false !== $object = $type::createFromFormat($defaultDateTimeFormat, $data, $timezone)) {
                    return $this->enforceTimezone($object, $context);
                }
            }

            $dateTimeObject = new $type($data, $timezone);

            if (null !== $defaultDateTimeFormat) {
                trigger_deprecation('symfony/serializer', '8.1', \sprintf('A "%s" will be thrown when a date could not be parsed using the default format "%s".', NotNormalizableValueException::class, $defaultDateTimeFormat));
            }

            return $this->enforceTimezone($dateTimeObject, $context);
        } catch (NotNormalizableValueException $e) {
            throw $e;
        } catch (\Exception $e) {
            throw NotNormalizableValueException::createForUnexpectedDataType($e->getMessage(), $data, ['string'], $context['deserialization_path'] ?? null, false, $e->getCode(), $e);
        }
    }

    public function supportsDenormalization(mixed $data, string $type, ?string $format = null, array $context = []): bool
    {
        return is_a($type, \DateTimeInterface::class, true);
    }

    /**
     * Formats datetime errors.
     *
     * @return string[]