狛ログ

2022年10月26日水曜日

【Laravel】created_atの日付フォーマットを変更する方法。

こんにちは、オフィス狛 技術部のmmm(むー)です。

以前、Laravelのプロジェクトで、日付のフォーマットを編集したかったのですが、レスポンスの項目名がcreated_at の場合、うまく変換できず少しはまりました。

その時、調べたことについて記事に残します。

前提条件

■Laravel バージョン
$ php artisan -V
Laravel Framework 8.27.0


■SQL Server バージョン
SELECT @@VERSION;
Microsoft SQL Server 2017 (RTM-CU30) (KB5013756) - 14.0.3451.2 (X64)  	Jun 22 2022 18:20:15  	Copyright (C) 2017 Microsoft Corporation 	Developer Edition (64-bit) on Linux (Ubuntu 18.04.6 LTS)


1. したかったこと

当初、SQLでフォーマットを指定して、created_at カラムの値をレスポンスしたかったのですが、期待した形の値が取得できませんでした。
※コードは必要な箇所以外、簡易化して記載します。
127は「ISO 8601 (タイム ゾーン Z)」となります。
class ConditionsController extends Controller
{
    public function index(Request $request)
    {

			$conditions = Condition::select(
			            DB::raw("CONVERT(VARCHAR, created_at, 127) as created_at")
			        )->get()->first();

			return response()->json($conditions);
    }
}

/*
■結果
{
    "created_at": "2022-09-07T02:48:46.947000Z"
}
*/

本来、「2022-09-07T11:48:46.947」のようなフォーマットになる想定でしたが、
created_atの値は「2022-09-07T02:48:46.947000Z」でした。

一方、下記は全く同じ書き方ですが、取得するカラム名が created_at ではない場合、期待通りにフォーマットを変換することができました。
class ConditionsController extends Controller
{
    public function index(Request $request)
    {

			$conditions = Condition::select(
			            DB::raw("CONVERT(VARCHAR, created_at, 127) as test") // 別名でtestを設定
			        )->get()->first();

			return response()->json($conditions);
    }
}

/*
■結果
{
    "test": "2022-09-07T11:48:46.947"
}
*/

created_atカラムに、testという別名を付けると、値は「2022-09-07T11:48:46.947」でした。

2. 原因と解決策

調査した結果、created_atupdated_atはデフォルトの場合、EloquentがCarbonインスタンスへ変換していることがわかりました。
Modelから返ってきた値をCarbonのフォーマットを使用して編集するように修正しました。
class ConditionsController extends Controller
{
    public function index(Request $request)
    {

			$conditions = Condition::select(
			            DB::raw("CONVERT(VARCHAR, created_at, 127) as created_at")
			        )->get()->first();
			$response['created_at'] = $conditions['created_at']->toIso8601String(); // 変換処理を追記

			return response()->json($response);
    }
}

/*
■結果
{
    "created_at": "2022-09-07T11:48:46+09:00"
}
*/

今回は toIso8601String() を使用しましたが、基本的なフォーマットは下記ページに用意されています。
参考:https://carbon.nesbot.com/docs/#api-conversion

3. 補足

今回はControllerでフォーマットの修正を行いましたが、Modelで下記のように、属性を指定してフォーマットを指定することもできます。
protected $casts = [
    'created_at' => 'datetime:Y/m/d',
];

さらに、Laravelで get...Attribute (...は加工したい項目名)と記載して、フォーマットを指定することも可能です。
public function getCreatedAtAttribute($value)
{
    return Carbon::parse($value)->format('Y/m/d');
}

上記は一例となります。Laravelでは様々な機能が用意されているので、もっといろんな方法があると思います。

参考になりましたら、幸いです。
,

0 件のコメント:

コメントを投稿