Doctrine的日期字段 - 如何编写查询

时间:2013-06-10 06:32:02

标签: date symfony doctrine-orm

我正在使用Symfony2和Doctrine。

我有一个日期字段,现在是:

/**
  * @ORM\Column(type="date")
  */
 protected $date;

在我的表单中,我使用文本字段来避免Chrome默认的datepicker,但我在数据库中插入了DateTime对象:

if ($request->isMethod('POST')) {
        $form->bind($request);

        //Convert string date to DateTime object and send it to database as object
        $dateObj = \DateTime::createfromformat('d-m-Y', $expense->getDate());
        $expense->setDate($dateObj);
        // ...

然后我想查找具有特定日期的所有项目:

public function findExpensesForDate($user, $date)
{
    $q = $this
        ->createQueryBuilder('e')
        ->where('e.date = :date')
        ->andWhere('e.user = :user')
        ->setParameter('date', $date)
        ->setParameter('user', $user)
         ->getQuery();

    return $q->getResult();
}

并将其称为:

$expenses_for_today = $this->repository->findExpensesForDate($this->user, $today);

时不返回任何内容
$today = new /DateTime();

并在

时返回结果
$today_obj = new /DateTime();
$today = $today_obj->format('Y-m-d'); 

那么为什么当我将日期作为对象时,这不起作用?使用日期字段的原因是不是利用DateTime对象的查询?我想我错过了一些微不足道的重要事情,但我看不清楚是什么,或者我不能很好地理解这种情况。我的理解是这样的:字段是date类型,所以我应该在其中插入DateTime对象,在查询时我也应该使用DateTime对象。你能帮我解决这个问题吗?

P.S。:我尝试将字段更改为日期时间:

 /**
  * @ORM\Column(type="datetime")
  */
 protected $date;

但没有变化。

使用字符串查询是否可行?在查询时,我会获得使用对象的优势吗?

2 个答案:

答案 0 :(得分:6)

我认为这是因为DateTime对象太具体而且还有小时,分钟和秒,所以它不能等于数据库中的注册日期!

如果您想使用DateTime对象,您需要获取当天开始日期和结束日期以获取当天的所有结果!您必须比较日期间隔以获取它之间的所有日期。

首先,获取当天的开始日期和结束日期(为简化起见,我们将在第二天开始时将结束日期作为基础,我们将在请求中将其排除在外):

$fromDate = new \DateTime('now'); // Have for example 2013-06-10 09:53:21
$fromDate->setTime(0, 0, 0); // Modify to 2013-06-10 00:00:00, beginning of the day

$toDate = clone $fromDate;
$toDate->modify('+1 day'); // Have 2013-06-11 00:00:00

修改你的方法:

public function findExpensesForDate($user, $fromDate, $toDate)
{
    $q = $this
        ->createQueryBuilder('e')
        ->where('e.date >= :fromDate')
        ->andWhere('e.date < :toDate')
        ->andWhere('e.user = :user')
        ->setParameter('fromDate', $fromDate)
        ->setParameter('toDate', $toDate)
        ->setParameter('user', $user)
         ->getQuery();

    return $q->getResult();
}

这就是全部,它应该有效,这里是脚本:

$expenses_for_today = $this->repository->findExpensesForDate($this->user, $fromDate, $toDate);

因此,您将获得 2013-06-10 00:00:00 2013-06-11 00:00:00 之间的所有日期(不包括在内) ),那么结果当天!

答案 1 :(得分:0)

正如其他人所说,由于日期时间中的时间

然而我为什么要回答?

因为我想让您了解$qb->expr()->between()功能。

以下代码段来自我的ReservationRepository我需要查找给定日期($today)的预订。我的预订包含dateFromdateTo属性。

    if(null !== $today) {
        $today0 = new \DateTime($today->format("Y-m-d"));
        $today23 = new \DateTime($today->format("Y-m-d"));

        $today0->setTime(0,0,0);
        $today23->setTime(23,59,59);

        $qb->where($qb->expr()->orX(
            $qb->expr()->orX(
                $qb->expr()->between('r.dateFrom', ':today0', ':today23'),
                $qb->expr()->between('r.dateTo', ':today0', ':today23')
            ),
            $qb->expr()->andX(
                $qb->expr()->lte('r.dateFrom', ':today23'),
                $qb->expr()->gte('r.dateTo', ':today0')
            )
        ));
        $qb->setParameter('today0', $today0);
        $qb->setParameter('today23', $today23);
    }

在此示例中,函数between()为我节省了两行代码,我发现它更强可读