Doctrine 将 DateTime 对象的错误值存储在 DB 中
Doctrine is storing the wrong value in DB from a DateTime object
我有以下实体:
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
class:
中有这个方法
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
?
让我们逐行浏览您的代码。
$entity->setStartDate($agreement->getEndDate()->modify('+1 day'));
modify()
改变调用它的 DateTime
对象。
此行向 $agreement->getEndDate()
添加了 +1 天,并且 相同的 日期时间传递给 $entity->setStartDate()
。所以 $agreement->getEndDate()
和 $entity->getStartDate()
都会 return 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
来避免所有这些不必要的对象引用问题。
您尝试保留的对象似乎有问题。当您进行 dump() 时,您会得到正确的结果,但稍后会修改 datetime 对象,因此当您保留该对象时,所有值都会得到您最后的 datetime 结果。
我建议您在日期时间对象中创建 "clone",并单独设置值,如下所示:
$oDatetime1 = clone($agreement->getEndDate());
$oDatetime2 = clone($agreement->getEndDate());
$entity->setStartDate($oDatetime1->modify('+1 day'));
$entity->setEndDate($oDatetime2->modify("+1 day +{$year} year"));
我有以下实体:
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
class:
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
?
让我们逐行浏览您的代码。
$entity->setStartDate($agreement->getEndDate()->modify('+1 day'));
modify()
改变调用它的 DateTime
对象。
此行向 $agreement->getEndDate()
添加了 +1 天,并且 相同的 日期时间传递给 $entity->setStartDate()
。所以 $agreement->getEndDate()
和 $entity->getStartDate()
都会 return 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
来避免所有这些不必要的对象引用问题。
您尝试保留的对象似乎有问题。当您进行 dump() 时,您会得到正确的结果,但稍后会修改 datetime 对象,因此当您保留该对象时,所有值都会得到您最后的 datetime 结果。 我建议您在日期时间对象中创建 "clone",并单独设置值,如下所示:
$oDatetime1 = clone($agreement->getEndDate());
$oDatetime2 = clone($agreement->getEndDate());
$entity->setStartDate($oDatetime1->modify('+1 day'));
$entity->setEndDate($oDatetime2->modify("+1 day +{$year} year"));