Невозможно создать экземпляр DateTime из сериализованных данных

У меня проблема с датой. Может я что-то не понимаю в процессе сериализации, но, когда, я отправляю дату и время в Api-Platform (Symfony) например

dateEvaluation: "2017-12-05T11:52:00.000Z"

Я получаю это сообщение об ошибке

Cannot create an instance of DateTime from serialized data because its constructor requires parameter "time" to be present.

Это моя Сущность

<?php

namespace App\Entity;

use ApiPlatform\Core\Annotation\ApiResource;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation\Groups;

/**
 * @ORM\Entity(repositoryClass="App\Repository\EvaluationRepository")
 * @ORM\HasLifecycleCallbacks()
 * @ApiResource(attributes={
 *     "normalization_context"={
 *              "groups"={"Evaluation"}
 *              }
 *     })
 */
class Evaluation
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     * @Groups({"NotesEvaluations", "Evaluation"})
     */
    private $id;

    /**
     * @var \DateTime
     * @ORM\Column(type="datetime")
     * @Groups({"Evaluation"})
     */
    private $created;

    /**
     * @var \DateTime
     * @ORM\Column(type="datetime")
     * @Groups({"Evaluation"})
     */
    private $updated;

    /**
     * @var \DateTime
     * @ORM\Column(type="datetime")
     * @Groups({"Evaluation"})
     */
    private $dateEvaluation;

    /**
     * @var string
     *
     * @ORM\Column(type="text")
     * @Groups({"Evaluation"})
     */
    private $commentaire;

    /**
     * @var
     *
     * @ORM\ManyToOne(targetEntity="App\Entity\Personnel")
     * @Groups({"NotesEvaluations", "Evaluation"})
     */
    private $auteur;

    /**
     * @var
     *
     * @ORM\ManyToMany(targetEntity="App\Entity\Personnel")
     */
    private $autorises;

    /**
     * @var integer
     *
     * @ORM\Column(type="integer")
     */
    private $annee;

    /**
     * @var
     *
     * @ORM\ManyToOne(targetEntity="App\Entity\Module", inversedBy="evaluations")
     * @Groups({"Evaluation"})
     */
    private $module;

    /**
     * @var Boolean
     *
     * @ORM\Column(type="boolean")
     * @Groups({"NotesEvaluations"})
     */
    private $visible;

    /**
     * @var Boolean
     *
     * @ORM\Column(type="boolean")
     * @Groups({"NotesEvaluations"})
     */
    private $modifiable;

    /**
     * @var
     *
     * @ORM\ManyToOne(targetEntity="App\Entity\TypeGroupe")
     * @Groups({"Evaluation"})
     */
    private $typegroupe;

    /**
     * @var float
     *
     * @ORM\Column(type="decimal")
     * @Groups({"Evaluation"})
     */
    private $coefficient;

    /**
     * @return float
     */
    public function getCoefficient(): float
    {
        return $this->coefficient;
    }

    /**
     * @return mixed
     */
    public function getTypegroupe()
    {
        return $this->typegroupe;
    }

    /**
     * @param mixed $typegroupe
     */
    public function setTypegroupe($typegroupe): void
    {
        $this->typegroupe = $typegroupe;
    }

    /**
     * @return \DateTime
     */
    public function getDateEvaluation(): \DateTime
    {
        return $this->dateEvaluation;
    }

    /**
     * @param \DateTime $dateEvaluation
     */
    public function setDateEvaluation(\DateTime $dateEvaluation): void
    {
        $this->dateEvaluation = $dateEvaluation;
    }

    /**
     * @return string
     */
    public function getCommentaire(): string
    {
        return $this->commentaire;
    }

    /**
     * @param string $commentaire
     */
    public function setCommentaire(string $commentaire): void
    {
        $this->commentaire = $commentaire;
    }

    /**
     * @param float $coefficient
     */
    public function setCoefficient(float $coefficient): void
    {
        $this->coefficient = $coefficient;
    }

    /**
     * @return mixed
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * @return \DateTime
     */
    public function getCreated(): \DateTime
    {
        return $this->created;
    }

    /**
     * @param \DateTime $created
     */
    public function setCreated(\DateTime $created): void
    {
        $this->created = $created;
    }

    /**
     * @return \DateTime
     */
    public function getUpdated(): \DateTime
    {
        return $this->updated;
    }

    /**
     * @param \DateTime $updated
     */
    public function setUpdated(\DateTime $updated): void
    {
        $this->updated = $updated;
    }

    /**
     * @return mixed
     */
    public function getAuteur()
    {
        return $this->auteur;
    }

    /**
     * @param mixed $auteur
     */
    public function setAuteur($auteur): void
    {
        $this->auteur = $auteur;
    }

    /**
     * @return mixed
     */
    public function getAutorises()
    {
        return $this->autorises;
    }

    /**
     * @param mixed $autorises
     */
    public function setAutorises($autorises): void
    {
        $this->autorises = $autorises;
    }

    /**
     * @return int
     */
    public function getAnnee(): int
    {
        return $this->annee;
    }

    /**
     * @param int $annee
     */
    public function setAnnee(int $annee): void
    {
        $this->annee = $annee;
    }

    /**
     * @return mixed
     */
    public function getModule()
    {
        return $this->module;
    }

    /**
     * @param mixed $module
     */
    public function setModule($module): void
    {
        $this->module = $module;
    }

    /**
     * @return bool
     */
    public function isVisible(): bool
    {
        return $this->visible;
    }

    /**
     * @param bool $visible
     */
    public function setVisible(bool $visible): void
    {
        $this->visible = $visible;
    }

    /**
     * @return bool
     */
    public function isModifiable(): bool
    {
        return $this->modifiable;
    }

    /**
     * @param bool $modifiable
     */
    public function setModifiable(bool $modifiable): void
    {
        $this->modifiable = $modifiable;
    }

    /**
     * @ORM\PreUpdate
     */
    public function updateDate(): void
    {
        $this->setUpdated(new \Datetime());
    }

    public function __construct()
    {
        $this->setCreated(new \Datetime());
        $this->setUpdated(new \Datetime());

    }
}

Я не понимаю, почему "время" отсутствует. Может быть, это для созданных или обновленных полей? В любом случае, созданные и обновленные поля возвращают с помощью ApiPlatform объект с часовым поясом...

created:
{timezone: {name: "Europe/Paris",…}, offset: 561, timestamp: -62169984561}
offset:561
timestamp:-62169984561
timezone:{name: "Europe/Paris",…}

Спасибо за вашу помощь. Дэйвид


person DAnnebicque    schedule 03.01.2018    source источник
comment
Какую версию платформы API вы используете? Проверьте его с помощью команды composer show, а также попробуйте обновить его до последней версии. Обычно платформа API должна возвращать и принимать даты в формате ISO8610.   -  person Vadim Ashikhman    schedule 03.01.2018
comment
Спасибо @Вадим. Я использую эту версию платформы API api-platform/api-pack v1.0.1 A pack for API Platform api-platform/core v2.1.4 The ultimate solution to create web APIs.   -  person DAnnebicque    schedule 04.01.2018
comment
@DAnnebicque ты решил свою проблему? Я столкнулся с той же проблемой.   -  person Ugo T.    schedule 03.02.2018
comment
@Ты получил. Не совсем. У меня был конфликт с другим сериализатором. Но если я удалю его, я больше не смогу управлять загрузкой.   -  person DAnnebicque    schedule 04.02.2018


Ответы (4)


Я нашел способ справиться с этой ошибкой, который работает для меня. Я объявляю DateTimeNormalizer в моем config.yml следующим образом:

datetime_normalizer:
    class: Symfony\Component\Serializer\Normalizer\DateTimeNormalizer
    public: false
    tags: [serializer.normalizer]

Я надеюсь, что это поможет вам!

person Ugo T.    schedule 05.02.2018
comment
Благодарность! Похоже, что если вы объявите службу с тегом serializer.normalizer, она перезапишет нормализаторы фреймворка по умолчанию. документ об этом слишком легкий - person a11r; 31.05.2018

В v1.1 использование класса \DateTimeImmutable вместо \DateTime — это то, что API-платформа ожидает по умолчанию.

class Evaluation {
    public function __construct()
    {
        $this->setCreated(new \DateTimeImmutable());
        $this->setUpdated(new \DateTimeImmutable());
    }
}
person Nicolas Janel    schedule 11.07.2018

Измените \DateTime в своей сущности на \DateTimeInterface. Он должен работать.

person Frantisek    schedule 25.07.2019
comment
это не связано - person Andrzej Moroz; 31.07.2020

В моем случае я использовал компонент Serializer Symfony без проекта Symfony, и в процессе денормализации у меня возникла эта проблема, поэтому мне пришлось добавить DateTimeNormalizer перед ObjectNormalizer в массиве нормализаторов следующим образом:

 $serializer = new Serializer([new DateTimeNormalizer(), new ObjectNormalizer(null, new CamelCaseToSnakeCaseNameConverter())]);

Обратите внимание, что порядок здесь важен.

person Albeis    schedule 19.03.2021