Doctrine хранит неверное значение в БД из объекта DateTime

У меня есть следующая сущность:

use Doctrine\ORM\Mapping as ORM;
use Gedmo\Timestampable\Traits\TimestampableEntity;

class Quote
{
use SourceTrait;
use TimestampableEntity;

private $quoteId;

private $startDate;

private $endDate;public function getStartDate(): ?\DateTime
{
return $this->startDate;
}public function setStartDate(\DateTime $startDate)
{
$this->startDate = $startDate;
}

public function getEndDate(): ?\DateTime
{
return $this->endDate;
}public function setEndDate(\DateTime $endDate)
{
$this->endDate = $endDate;
}

}

и у меня есть этот метод в QuoteRepository учебный класс:

public function createQuoteHeader(Agreement $agreement): int
{
$em      = $this->getEntityManager();
$QuoteID = $this->getNewQuoteId();
$year    = $agreement->getEndDate()->diff($agreement->getStartDate(), true)->y > 0
? $agreement->getEndDate()->diff($agreement->getStartDate(), true)->y
: 0;

dump($year);
dump(gettype($year));
dump($agreement->getEndDate());

$entity = new Quote();
...
$entity->setStartDate($agreement->getEndDate()->modify('+1 day'));
dump($agreement->getStartDate());
$entity->setEndDate($agreement->getEndDate()->modify("+1 day +{$year} year"));
dump($agreement->getEndDate());
...

$em->persist($entity);
$em->flush();

return $entity->getQuoteId();
}

Выход из dump() выше приведены ниже (в том же порядке, что и в коде):

0
"integer"DateTime {#3005
+"date": "2017-03-21 00:00:00.000000"+"timezone_type": 3
+"timezone": "UTC"}
DateTime {#3004
+"date": "2016-03-22 00:00:00.000000"+"timezone_type": 3
+"timezone": "UTC"}
DateTime {#3005
+"date": "2017-03-23 00:00:00.000000"+"timezone_type": 3
+"timezone": "UTC"}

Каким-то образом неправильные значения вставляются в БД:

введите описание изображения здесь

Может быть, я что-то упустил, но не должно быть StartDate равно 2016-03-22 00:00:00??

0

Решение

Давайте пройдемся по вашему коду построчно.

$entity->setStartDate($agreement->getEndDate()->modify('+1 day'));

modify() мутирует DateTime объект, к которому он призван.
Эта строка добавила +1 день к $agreement->getEndDate() И так же DateTime передается $entity->setStartDate(), Так ОБА $agreement->getEndDate() а также $entity->getStartDate() вернется 2017-03-22!

dump($agreement->getStartDate());

Вы сбросили неправильную дату, следовательно, 2016-03-22, маскируя ошибку. Должно быть dump($entity->getStartDate()); и ты бы заметил.

$entity->setEndDate($agreement->getEndDate()->modify("+1 day +{$year} year"));

поскольку $agreement->getEndDate() теперь равно 2017-03-22, +1 день +0 год приведет к $entity->getEndDate() быть равным 2017-03-23.

Я рекомендую использовать DateTimeImmutable чтобы избежать всех этих ненужных проблем со ссылками на объекты.

2

Другие решения

Кажется, проблема с объектом, который вы пытаетесь сохранить. Вы получаете правильный результат, когда выполняете dump (), но объект datetime изменяется позже, поэтому, когда вы сохраняете объект, все значения получают ваш последний результат datetime.
Я рекомендую вам сделать «клон» в ваших объектах datetime и установить значения отдельно, примерно так:

$oDatetime1  = clone($agreement->getEndDate());
$oDatetime2  = clone($agreement->getEndDate());

$entity->setStartDate($oDatetime1->modify('+1 day'));
$entity->setEndDate($oDatetime2->modify("+1 day +{$year} year"));
1

По вопросам рекламы [email protected]