我想找到两个日期之间的冲突。问题是在数据库中我单独日期和时间字段。所以我做了concat(日期,时间):
public function findConflictingEvents($datef,$dateu,$personID){
$from = $datef->format('Y-m-d H:i:s');
$until = $dateu->format('Y-m-d H:i:s');
$qb = $this->createQueryBuilder('event');
$qb->select('event')
->innerJoin('event.visitors', 'p')
->add('where',
$qb->expr()->orX(
$qb->expr()->andX(
$qb->expr()->lte(':until', $qb->expr()->concat('event.date_until',
$qb->expr()->literal(' '), 'event.time_until')),
$qb->expr()->gte(':until', $qb->expr()->concat('event.date_from',
$qb->expr()->literal(' '), 'event.time_from'))
),
$qb->expr()->andX(
$qb->expr()->lte(':from', $qb->expr()->concat('event.date_until',
$qb->expr()->literal(' '), 'event.time_until')),
$qb->expr()->gte(':from', $qb->expr()->concat('event.date_from',
$qb->expr()->literal(' '), 'event.time_from'))
),
$qb->expr()->andX(
$qb->expr()->lte(':from', $qb->expr()->concat('event.date_from',
$qb->expr()->literal(' '), 'event.time_from')),
$qb->expr()->gte(':until', $qb->expr()->concat('event.date_until',
$qb->expr()->literal(' '), 'event.time_until'))
)
)
)
->andWhere('p.id = ?1')
->setParameter('from', $from)
->setParameter('until', $until)
->setParameter(1, $personID);
return $qb->getQuery()->getResult();
}
但查询会产生意外结果。我认为我应该转换为时间戳并进行比较。
提前谢谢!
答案 0 :(得分:1)
绑定参数和检查日期时间范围的表达式分配错误。连接也需要两个参数,你需要再次使用它作为第三部分。
此外,在使用Doctrine时,最好将数据库视为对象而不是表。尽可能使用对象。返回一个新的ArrayCollection
而不是一个数组,并允许您的存储库方法接受Person
的实例并从那里获取ID。
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\QueryBuilder;
use Your\Bundle\Entity\Event;
use Your\Bundle\Entity\Person;
class EventRepository extends EntityRepository
{
/**
* @param \DateTime $from
* @param \DateTime $until
* @param Person $person
*
* @return Event[]|Collection
*/
public function findConflictingEvents(\DateTime $from, \DateTime $until, Person $person)
{
$qb = $this->createQueryBuilder('event');
$qb->select('event')
->innerJoin('event.visitors', 'p')
->add('where',
$qb->expr()->orX(
$qb->expr()->andX(
$qb->expr()->lte(
$this->buildDateTimeUntilExpression($qb),
':until'
),
$qb->expr()->gte(
$this->buildDateTimeFromExpression($qb),
':until'
)
),
$qb->expr()->andX(
$qb->expr()->lte(
$this->buildDateTimeUntilExpression($qb),
':from'
),
$qb->expr()->gte(
$this->buildDateTimeFromExpression($qb),
':from'
)
),
$qb->expr()->andX(
$qb->expr()->lte(
$this->buildDateTimeFromExpression($qb),
':from'
),
$qb->expr()->gte(
$this->buildDateTimeUntilExpression($qb),
':until'
)
)
)
)
->andWhere('p.id = ?1')
->setParameter('from', $from)
->setParameter('until', $until)
->setParameter(1, $person->getId());
;
return new ArrayCollection($qb->getQuery()->getResult());
}
/**
* @param QueryBuilder $qb
*
* @return mixed
*/
private function buildDateTimeUntilExpression(QueryBuilder $qb)
{
return $qb->expr()->concat('event.dateUntil', $qb->expr()->concat($qb->expr()->literal(' '), 'event.timeUntil'));
}
/**
* @param QueryBuilder $qb
*
* @return mixed
*/
private function buildDateTimeFromExpression(QueryBuilder $qb)
{
return $qb->expr()->concat('event.dateFrom', $qb->expr()->concat($qb->expr()->literal(' '), 'event.timeFrom'));
}
}