Doctrine Mongodb ODM и запрос DateTime

Я мог бы использовать некоторую помощь по этой проблеме. Я создаю приложение, использующее Symfony2 + mongodb + doctrine. Я просто хочу использовать Doctrine ODM для запроса всех пользователей, которые вошли в систему за последние 5 минут. У меня есть коллекция пользователей с полем даты с именем date_last_login.

Поэтому я пытаюсь использовать querybuilder следующим образом:

<?php // Creating a DateTime object and susbtract 5 min from now // local time is 15:40:05, timezone: 'Europe/Paris' $_dateTime = new \DateTime(); $_interval5Min = new \DateInterval('PT5M'); $_dateTime->sub($_interval5Min); $query = $this->createQueryBuilder('User') ->field('date_last_login')->gte($_dateTime) ->getQuery(); ->execute(); 

Когда я посмотрел собранный запрос с использованием профилировщика symfony2, вот что я получил:

 db.User.find({ "date_last_login": { "$gte": new Date("Fri, 23 Dec 2011 15:30:05 +0100") } }); 

Кажется хорошо, кроме того, что дата на 10 минут раньше, а не 5 минут? Я просто не понимаю. Если я сброшу свой объект php DateTime, дата верна: 2011-12-23 15:35:05 (за пять минут до 15:40).

Поэтому я попытался собрать тот же запрос, не вычитая никаких минут, и на этот раз все в порядке:

 <?php // local time is 15:50:00 $query = $this->createQueryBuilder('User') ->field('date_last_login')->gte(new \DateTime()) ->getQuery(); ->execute(); // query is ok: db.User.find({ "date_last_login": { "$gte": new Date("Fri, 23 Dec 2011 15:50:00 +0100") } }); 

Что я делаю не так ? Спасибо за помощь!

Вероятно, это связано с этой ошибкой PHP, которая была исправлена ​​в 5.3.3:

https://bugs.php.net/bug.php?id=50916

Чтобы создать построитель запросов для получения данных, когда date_last_login превышает 5 minutes есть 3 способа

1) создать объект DateTime с вашим форматом datetime и получить MongoDate timestamp из объекта DateTime затем создать объект MongoDate :

 $timeBefore5MinutesAgo = new \DateTime(date('Ymd H:i:s',\time() - 5 * 60)); $mongoDateBefore5MinutesAgo = new \MongoDate($currentDateWithTime->getTimestamp()); $query = $this->createQueryBuilder('User') ->field('date_last_login')->gte($mongoDateBefore5MinutesAgo) ->getQuery(); ->execute(); 

2) создайте объект MongoDate и используйте strtotime для преобразования вашего формата datetime в timestamp :

 $mongoDateBefore5MinutesAgo = new \MongoDate(strtotime(date('Ymd H:i:s',\time() - 5 * 60))); $query = $this->createQueryBuilder('User') ->field('date_last_login')->gte($mongoDateBefore5MinutesAgo) ->getQuery(); ->execute(); 

3) только в случае Doctrine 2 ODM вы можете просто создать объект DateTime с вашим форматом datetime`r:

 $timeBefore5MinutesAgo = new \DateTime(date('Ymd H:i:s',\time() - 5 * 60)); $query = $this->createQueryBuilder('User') ->field('date_last_login')->gte($timeBefore5MinutesAgo) ->getQuery(); ->execute(); 

все три способа создадут запрос:

 db.User.find({ "date_last_login": { "$gte": new ISODate("2014-03-15T19:35:08+02:00") } });