0

我有以下实体:

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??

4

2 回答 2

2

让我们逐行浏览您的代码。

$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来避免对象引用的所有这些不必要的问题。

于 2017-03-20T15:01:08.593 回答
1

您尝试保留的对象似乎有问题。当您进行转储()时,您将获得正确的结果,但日期时间对象稍后会被修改,因此当您持久保存该对象时,所有值都会获得您的最后一个日期时间结果。我建议您在日期时间对象中进行“克隆”,并单独设置值,如下所示:

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

$entity->setStartDate($oDatetime1->modify('+1 day'));
$entity->setEndDate($oDatetime2->modify("+1 day +{$year} year"));
于 2017-03-20T15:06:36.330 回答