You may notice that when you serialize the an Eloquent model using the toArray() method or a collection of Eloquent models, all timestamps, for example, created_at and updated_at will have a UTC timezone. However, when you serialize any date manually using Carbon the timezone is correct. Looks like it is a bug and the toArray() method ignores the Laravel timezone settings, but it is not. In this short article I will show how to fix wrong timezone in created_at in Laravel.
Laravel developers changed serialization rules for the toArray() and toJSON() methods. They decided to use ISO-8601 format and always provide time as UTC. You can read more about it here. You can use the following code to reproduce the behavior when Laravel timezone is not UTC:
app/Console/Commands/PrintUserCommand.php$user = \App\Models\User::all()->first();
dump(\config("app.timezone"));
dump((string)$user->created_at);
dump($user->toArray());

If you want Eloquent to respect Laravel timezone settings, you can override the serializeDate() method in the model. For example let’s try it for User:
app/Models/User.phpprotected function serializeDate(\DateTimeInterface $date)
{
return $date->format("Y-m-d H:i:s");
}

After this, all timestamps and dates will be serialized with a correct timezone:

This fix is also applied for collections of models.