以前、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_atとupdated_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では様々な機能が用意されているので、もっといろんな方法があると思います。
参考になりましたら、幸いです。
Laravel , PHP
0 件のコメント:
コメントを投稿