Doctrine正在从DateTime对象中将错误的值存储在DB中

时间:2017-03-20 14:41:13

标签: php symfony doctrine-orm doctrine symfony-3.2

我有以下实体:

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"
}

以某种方式在DB中插入了错误的值:

enter image description here

也许我错过了一些东西但不应该StartDate等于2016-03-22 00:00:00 ??

2 个答案:

答案 0 :(得分:2)

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

DateTime

modify() 改变调用它的$agreement->getEndDate()对象。 此行向$entity->setStartDate()添加+1天,相同 DateTime传递给$agreement->getEndDate()。因此$entity->getStartDate()dump($agreement->getStartDate()); 将返回2017-03-22!

dump($entity->getStartDate());

您转错了错误的日期,因此2016-03-22掩盖了错误。应该是$entity->setEndDate($agreement->getEndDate()->modify("+1 day +{$year} year")); ,你会注意到的。

$agreement->getEndDate()

由于$entity->getEndDate()现在等于2017-03-22,+ 1天+ 0年将导致$timestamp1 = strtotime("2017-01-01"); $timestamp2 = strtotime("2017-01-05"); $timeDiff = abs($timestamp1 - $timestamp2); $numberDays = $timeDiff/86400; $numberDays = intval($numberDays); 等于2017-03-23。

我建议使用DateTimeImmutable来避免对象引用带来的所有这些不必要的问题。

答案 1 :(得分:1)

您尝试保留的对象似乎存在问题。您在创建dump()时获得了正确的结果,但是稍后会修改datetime对象,因此当您持久保存该对象时,所有值都会获得您的上次日期时间结果。 我建议你在你的日期时间对象中制作“克隆”,然后单独设置值,如下所示:

function myFunction(key) {
    var str = "Text with Account Opening Member Onboarding Assignment Cube (AOMOA) string inside";
    var patt = new RegExp("(?:^|\\s)" + key.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&') + "(?!\\S)");
    return patt.test(str);
}

var key="Account Opening Member Onboarding Assignment Cube (AOMOA)";
console.log(myFunction(key));