LoginSignup
22
20

More than 5 years have passed since last update.

CakePHP3でDB取得時のDateTime型をフォーマット変換

Posted at

やりたかったことは至極単純。

MySQLのDateTime型で定義されている項目を、フォーマット変換してCSV出力させること。

CakePHP3初心者な事もあり、解決まで少々時間を要してしまったので、自分同様にCakePHP3初心者が同じ轍を踏まないようメモ書きを残しておきます。

CakePHP3のクエリビルダでDateTime型を取得

日時/日付のSQL取得方法は、各データベースによって仕様が異なる。

例えばこんな感じ↓↓↓
・Oracleの場合、SELECT TO_CHAR(date,'yyyy/mm/dd') FROM dual;
・MySQLの場合、SELECT DATE_FORMAT(now(),'%Y/%m/%d');
・postgreSQLの場合、SELECT TO_CHAR(current_timestamp, 'yyyy/mm/dd');

今回MySQL使ってたので、CakePHP3のクエリビルダでDATE_FORMATを使う手段をググッてみると、func()->date_format()で実現可能なことが分かった。

filename.rb
$created = $query->func()->date_format([
    'created' => 'identifier',
    "'%Y%m%d %k%i%s'" => 'literal'
]);
$modified = $query->func()->date_format([
    '$modified' => 'identifier',
    "'%Y%m%d %k%i%s'" => 'literal'
]);

コレをselectで指定すれば、確かにSQL上ではDATE_FORMATが指定されていたけど、どうにも返却される値が上手くフォーマットされていなかった。

filename.rb
id,作成日時,更新日時
1,"3/8/17, 5:08 PM","3/8/17, 5:08 PM"

CakePHP3でのdatetime型について

返却された配列をデバッグしてみると原因が分かった。

filename.rb
[0] => Array (
    [id] => 1
    [created] => Cake\I18n\FrozenTime Object (
        [time] => 2017-03-08T17:08:52+00:00
        [timezone] => UTC
        [fixedNowTime] => 
    )
    [modified] => Cake\I18n\FrozenTime Object (
        [time] => 2017-03-08T17:08:56+00:00
        [timezone] => UTC
        [fixedNowTime] => 
    )
)

FrozenTimeという見慣れぬObjectで返されているけど、どうやらdatetime型はCake\I18n\FrozenTimeで返されるらしい。ちなみにdate型は3.1迄はCake\I18n\FrozenDate、3.2からはCake\I18n\FrozenTimeになっている。

なので取得された配列(またはJSON)に対して、フォーマット変換することで解決しました。

filename.rb
$created = $data['created']->i18nFormat('YYYY/MM/dd HH:mm:ss');

ちゃんと公式HP確認してたら、何てこと無いんだろうけどね...

22
20
1

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
22
20