1
Help us understand the problem. What are the problem?

posted at

Laravel8でタイムゾーンが切り替わらない?

Laravel8で日時を扱っていた際、9時間時刻がズレる現象に陥った。
もちろん、config/app.phpの「timezone」は「Asia/Tokyo」に変更済み。

よくよく調べていくと、モデルからそのまま取り出した際は問題ないが、
toJson()をした場合のみ、9時間ズレることに気がついた。

Laravel7から、Date Serializationの仕様が変わったっぽい

これにより、Dateフォーマットが変更になっているだけでなく、
タイムゾーンが強制的にUTCになってしまうとのこと。
https://laravel.com/docs/7.x/upgrade#date-serialization

「Y-m-d H:i:s」フォーマットに変更する

ModelのserializeDate()をオーバーライドしろと書いてあるので、
Modelを継承した、BaseModelを作ろうと思ったのだが、Userモデルが厄介そうだった。

そのため、トレイトを使用した方法に切り替える。

app\Models\SerializeDate.php
<?php

namespace App\Models;

use DateTimeInterface;

trait SerializeDate
{
    /**
     * Prepare a date for array / JSON serialization.
     *
     * @param  \DateTimeInterface  $date
     * @return string
     */
    protected function serializeDate(DateTimeInterface $date)
    {
        return $date->format('Y-m-d H:i:s');
    }
}

上記のファイルを新規で作成し、
各モデルに以下のようにSerializeDateを追加する。

app\Models\User.php
<?php

namespace App\Models;

use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;

class User extends Authenticatable
{
    use HasFactory,
        Notifiable,
+       SerializeDate;

    protected $fillable = [
        'name',
        'email',
        'password',
    ];

    protected $hidden = [
        'password',
        'remember_token',
    ];

    protected $casts = [
        'email_verified_at' => 'datetime',
    ];
}

これによって、日時フォーマットが「Y-m-d H:i:s」となり、
当初の目的であった時刻の9時間ズレも解決した。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
1
Help us understand the problem. What are the problem?