【问题标题】:How to handle Query builder with date formats如何使用日期格式处理查询生成器
【发布时间】:2021-11-25 11:46:02
【问题描述】:

我只想显示 startdate 从明天开始的事件。我该如何进行?目前它也将 h:i:s 考虑在内。

public function display()
{
    $now = date('Y-m-d H:i:s');

    $this->loadModel('Events');
    $events = $this->Events
        ->find()
        ->contain(['Categories', 'Venues'])
        ->limit(5)
        ->order(['events.startdate' => 'ASC'])
        ->where(['events.startdate >' => $now]);
    $this->set('upcomingEvents', $events);
}

我试过了,但它不起作用:

public function display()
{
    $now = date('Y-m-d');

    $this->loadModel('Events');
    $events = $this->Events
        ->find()
        ->contain(['Categories', 'Venues'])
        ->limit(5)
        ->order(['events.startdate' => 'ASC'])
        ->where(['date_format("%Y-%m-%d", events.startdate)' => $now]);
    $this->set('upcomingEvents', $events);
}

【问题讨论】:

  • 试试:'Events.startdate'

标签: cakephp query-builder cakephp-4.x


【解决方案1】:

无需在查询中格式化日期并失去索引功能,而是与使用00:00:00 作为时间部分的日期时间字符串进行比较,例如一天的开始。

您可以使用date('Y-m-d 00:00:00') 轻松实现此目的,但是那是今天,而不是明天,您需要为date() 提供像date('Y-m-d 00:00:00', strtotime('+1 day')) 这样的时间戳。

您还可以使用 CakePHP 附带的日期时间功能。今天\Cake\Chronos\Date::tomorrow() 将创建一个代表2021-10-06 的日期对象,其中时间部分将始终为00:00:00

->where(['Events.startdate >=' => \Cake\Chronos\Date::tomorrow()])

ORM 会根据列类型自动格式化日期对象,因此对于您的 DATETIME 列,它最终会在 SQL 中为 2021-10-06 00:00:00

另见

【讨论】:

  • 总是更好,IMO,避免使用 date 函数,而是使用 Cake 提供的类,因为这些类包括设置要使用的日期的方法。这在单元测试时非常有用。
  • @GregSchmidt 哦,完全忘记了这一点。是的,能够在测试时设置固定时间是另一大优势!
  • 看起来大多数(甚至可能所有受支持的 DBMS)在进行较少/较大比较时甚至不需要时间部分,似乎在这些情况下,如果省略,他们默认假定 00:00:00。在过去的 20 年里,我怎么从来没有注意到这一点???
  • 谢谢你们!我什至没有在查询文档中找到 Cake 提供的类...
【解决方案2】:

不确定这是否是正确的方法,但它使用函数 DATA_FORMAT()

DATE_FORMAT(events.startdate, "%Y-%m-%d")

所以这里是查询:

public function display()
{
    $now = date('Y-m-d');

    $this->loadModel('Events');
    $events = $this->Events
        ->find()
        ->contain(['Categories', 'Venues'])
        ->limit(5)
        ->order(['events.startdate' => 'ASC'])
        ->where(['DATE_FORMAT(events.startdate, "%Y-%m-%d") >' => $now]);
        
    $this->set('upcomingEvents', $events);
}

或者我们也可以在条件数组中使用它

public function display()
{
    $this->loadModel('Events');
    $events = $this->Events
    ->find('all', array('conditions' => array('DATE_FORMAT(events.startdate, "%Y-%m-%d") >' => date('Y-m-d'))))
    ->contain(['Categories', 'Venues'])
    ->limit(5)
    ->order(['events.startdate' => 'ASC']);

    $this->set('upcomingEvents', $events);
}

【讨论】:

  • 再解释一下您为解决问题所做的工作。如果你这样做,它会提高答案的质量,如果你这样做,人们更有可能投票。审查结束。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-08-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-15
  • 1970-01-01
  • 2015-12-16
相关资源
最近更新 更多