Doctrine Mongodb ODM和DateTime查询

JuC*_*lot 4 php mongodb symfony doctrine-orm doctrine-odm

我可以在这个问题上使用一些帮助.我正在使用Symfony2 + mongodb + doctrine创建一个应用程序.我只想使用Doctrine ODM查询过去5分钟内登录过的所有用户.我有一个User集合,其中包含一个名为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();
Run Code Online (Sandbox Code Playgroud)

当我使用symfony2 profiler查看汇编的查询时,我得到的是:

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

看起来很好,除了日期提前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") } });
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么 ?谢谢您的帮助!

ahm*_*mdy 9

创建用于获取数据的查询构建器时date_last_login,5 minutes有3种方法

1)DateTime使用您的日期时间格式创建对象并timestampDateTime对象获取然后创建MongoDate对象:

$timeBefore5MinutesAgo  = new \DateTime(date('Y-m-d H:i:s',\time() - 5 * 60));
$mongoDateBefore5MinutesAgo = new \MongoDate($currentDateWithTime->getTimestamp());

$query = $this->createQueryBuilder('User')
    ->field('date_last_login')->gte($mongoDateBefore5MinutesAgo)
    ->getQuery();
    ->execute();
Run Code Online (Sandbox Code Playgroud)

2)创建MongoDate对象并使用strtotime将您的日期时间格式转换为timestamp:

$mongoDateBefore5MinutesAgo = new \MongoDate(strtotime(date('Y-m-d H:i:s',\time() - 5 * 60)));

$query = $this->createQueryBuilder('User')
    ->field('date_last_login')->gte($mongoDateBefore5MinutesAgo)
    ->getQuery();
    ->execute();
Run Code Online (Sandbox Code Playgroud)

3)只有在以下情况下Doctrine 2 ODM,你可以DateTime用你的日期时间格式创建对象:

$timeBefore5MinutesAgo  = new \DateTime(date('Y-m-d H:i:s',\time() - 5 * 60));

$query = $this->createQueryBuilder('User')
              ->field('date_last_login')->gte($timeBefore5MinutesAgo)
              ->getQuery();
              ->execute();
Run Code Online (Sandbox Code Playgroud)

所有3种方法都会创建查询:

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