CakePHP 4 で日時表示の初期フォーマットを設定する方法

はじめに

CakePHP 4 には日時用のクラスがあり、例えばデータベースに DATETIME 型で格納されている値は FrozenDate オブジェクトに変換されます。

このオブジェクトを echo すると、日時が自動的にフォーマットされて表示されます。
形式は設定ロケールによって変わり、例えば ja_JP が設定されている場合は 「2020/11/17 12:34:56」 になります。

他形式で出力したい場合は i18nFormat() を使うことができますが、毎回それを書くのは手間ですし、保守性も低下しますよね。

そこで今日は CakePHP 4 で、この日時表示時の初期フォーマットを設定する方法を紹介します。

今回使用したのは CakePHP 4.1.5 (cakephp/app 4.1.2) です。

目次
  1. 設定方法
  2. echo で文字列表示になる仕組み

1. 設定方法

FrozenTime::setToStringFormat() を使うことで、デフォルトの書式を設定できます。
これは AppController の Initialize() に書くのがいいでしょうか。

/src/Controller/AppController.php
// ↓ 追加
use Cake\I18n\FrozenTime;
...
    public function initialize(): void
    {
        ...
        // ↓ 追加
        FrozenTime::setToStringFormat('yyyy-MM-dd HH:mm:ss');
    }

日時のクラスは他に TimeDateFrozenDate もありますが、
それぞれに setToStringFormat() が実装されています。

全てのクラスで試せるサンプルコードを作りましたので、よろしければ学習等にご利用ください。

/src/Controller/SampleController.php
<?php
declare(strict_types=1);

namespace App\Controller;

use Cake\I18n\Date;
use Cake\I18n\FrozenDate;
use Cake\I18n\FrozenTime;
use Cake\I18n\Time;

class SampleController extends AppController
{
    public function initialize(): void
    {
        parent::initialize();

        Date::setToStringFormat('yyyy.MM.dd');
        Time::setToStringFormat('yyyy.MM.dd HH:mm:ss');
        FrozenDate::setToStringFormat('yyyy-MM-dd');
        FrozenTime::setToStringFormat('yyyy-MM-dd HH:mm:ss');
    }

    public function index()
    {
        echo '<h1>Date</h1>';
        echo Date::now();

        echo '<h1>Time</h1>';
        echo Time::now();

        echo '<h1>FrozenDate</h1>';
        echo FrozenDate::now();

        echo '<h1>FrozenTime</h1>';
        echo FrozenTime::now();

        exit;
    }
}

2. echo で文字列表示になる仕組み

FrozenDate などのオブジェクトを echo した際に文字列が表示される仕組みは、
下記 DateFormatTrait__toString() メソッドにあります。

/vendor/cakephp/cakephp/src/I18n/DateFormatTrait.php

__toString() は PHP のマジックメソッドの一つで、クラスが文字列に変換される場合にどんな値を返すかを実装できます。

DateFormatTrait では i18nFormat() したものを返すようにしていて、
FrozenDate などの各クラスにこのトレイトが追加されているので、
echo で指定書式の日時が表示されるんですね。