sagara.inkITエンジニアのまとめノート

LaravelのTimestampsを日付時刻形式にする(Y-m-d H:i:s)

Laravel7以降、デフォルトではCarbonインスタンスになるタイムスタンプを従来の Y-m-d H:i:s(yyyymmddhhiiss)での形式にします。

Laravel7からタイムスタンプの形式が変わった

Laravelが提供するMVCのモデル機能がEloquentです。
マイグレーションする際、timestamps()を定義することでタイムスタンプ型のcreated_at, updated_atカラムを定義できます。 Eloquentは、そのモデルのテーブルが変更または挿入されるときに自動的にその日時を設定してくれます。

Migrations

app/Database/migrations/some-migrations.php
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
  
return new class extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('flights', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('airline');
            $table->timestamps(); // created_at, updated_atカラムが追加される
        });
    }
    ...
};

この機能は便利なのですが、Laravel7以降では、Eloquentモデルでそのデータを取得する際にCarbonインスタンスを 返すようになり、さらにJSONにするとISO-8601形式の表記(2019-12-02T20:01:00.283041Zのような形式) になってしまいます。データを表示する際、この形式では見栄えが良くありません。

Laravel6以前でのY-m-d H:i:s(yyyymmddhhiiss)の表記に戻したいということがあるかもしれません。

ModelのserializeDateメソッドを上書き

Laravel7への移行ガイドの中でその説明がされています。
従来の形式で表示したい場合は、EloquentモデルのserializedDateをY-m-d H:i:sで返すようにオーバーライドします。

Upgrade Guide

app/Models/Model.php

<?php

namespace ApiModules\Contract\Models;

use Illuminate\Database\Eloquent\Model as BaseModel;
use DateTimeInterface;

class Model extends BaseModel
{    
    ...

    protected function serializeDate(DateTimeInterface $date)
    {
        return $date->format('Y-m-d H:i:s');
    }
}

上記はデフォルトのModelに噛ませる形でアプリケーション共通のModelを定義し、 他のEloquentモデルはこのModelを使うことで全てのEloquentモデルでY-m-d H:i:s形式で表示することができるようになります。

補足

Laravelのtimestampsで定義されるcreated_at,updated_atなどのカラムはフレームワーク内部的な値なので アプリケーションとしてこれらの値を使うべきでないという意見もあります。
アプリケーションとして表示する値や日時は、これらのタイムスタンプとは別に定義してあげるのが良いかもしれません。