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"));