LoginSignup
6
4

More than 5 years have passed since last update.

CakePHP3でDATE_FORMAT

Last updated at Posted at 2018-01-31
  • Datetimeで保存されているデータをDATE_FORMATY-m-dの形式を条件として絞り込みたい。
  • 難しいことではないのですが、少しはまったので備忘録。

CakePHP2とCakePHP3での書き方の違い

CakePHP2の場合

CakePHP2まではconditionsに思ったままの事を書けばできます。

$conditions = ["DATE_FORMAT(created, '%Y-%m-%d')" => 'CURRENT_DATE()'];

これでCURRENT_DATE()で絞り込んだデータを取得することができます。

CakePHP3の場合

CakePHP3でも似たようなものだと思っていたので下記の様に記述。
(ただし=をつけないとエラーが発生するので注意)

$query->where([
    "DATE_FORMAT(created, '%Y-%m-%d') =" => $query->func()->now('date')
])

CURRENT_DATE()をCakePHP3っぽく$query->func()->now('date')と記述。

問題

一見上記で問題がないように動作していたのですが、データがうまく取れていないことが発覚。
出力されたSQLのWHEREを確認してみると、

WHERE 
  DATE_FORMAT(created, '%y-%m-%d') = (
    CURRENT_DATE()
  ) 

%Yで指定したはずが%yになっています。
……なぜ。

対策

1. func()->date_format()を使う

そのまま記述するのが原因のようなのでfunc()を使用してDATE_FORMATを記述してみます。

$created = $query->func()->date_format([
    'created' => 'identifier',
    "'%Y-%m-%d'" => 'literal'
]);

$query->where([
    $created => $query->func()->now('date')
]);

Illegal offset type…… :neutral_face:
条件に使用する想定ではないのでしょうか、怒られます。
でも$query->func()->now('date') も使いたい。(逆にしてみたけどやはり怒られる)

2. よりCakePHP3っぽい書き方にする

func()->date_format()を使用しつつ、よりCakePHP3の記述に近づけてみます。

$created = $query->func()->date_format([
    'created' => 'identifier',
    "'%Y-%m-%d'" => 'literal'
]);

$today = $query->func()->now('date');

$query->where(function ($exp) use ($created, $today) {
   return $exp->eq($created, $today);
});

発行されたSQLを確認しても%Yのまま。
無事に希望通りのデータが取得できました。

6
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
4