2

我正在使用 Symfony2 和 Doctrine。

我有一个日期字段,这里是:

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

在我的表单中,我使用文本字段来避免 Chrome 默认日期选择器,但我在数据库中插入 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 对象的查询吗?我想我错过了一些微不足道和重要的东西,但我就是看不到什么,或者我不太了解情况。我的理解是这样的:该字段是日期类型,所以我应该在其中插入 DateTime 对象,并且在查询时我也应该使用 DateTime 对象。你能帮我解决这个问题吗?

PS:我尝试将字段更改为日期时间:

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

但没有任何变化。

用字符串查询是否可以并且很好?以这种方式查询时,我会获得使用对象的优势吗?

4

2 回答 2

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:002013-06-11 00:00:00之间的所有日期(不包括),所以当天的结果!

于 2013-06-10T08:04:03.837 回答
0

正如其他人所提到的,那是由于Date Time中的时间

然而我为什么要回答?

因为我想让你知道这个$qb->expr()->between()功能。

以下片段来自我ReservationRepository需要查找给定日期($today)的预订的地方。我的保留既有 adateFrom又有dateTo属性。

    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()在这个示例中为我节省了两行代码,发现它更具可读性

于 2015-01-14T14:13:14.883 回答