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と adateTo属性の両方があります。

    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()によって 2 行のコードが節約され、より読みやすくなっいます。

于 2015-01-14T14:13:14.883 に答える