In Laravel, there's a convenient way to transform date/time DB fields to Carbon objects automatically. In fact, there are two ways, let me tell you about both.
Inconvenience: With No Casting
Imagine you have a DB field projects.activated_at
with values in the DB like "2022-10-05" or "2021-12-23", so a typical YYYY-MM-DD.
What if you want to show them in another format to users, like "m/d/Y"?
You need to convert them every time, right? And Carbon library would help, something like this:
Carbon::createFromFormat('Y-m-d', $project->activated_at) ->format('m/d/Y');
So, you need to create a Carbon object yourself, and then you can convert it to whatever you want.
Every time in every place where you want to show that value.
Wouldn't it be cool to have something like this?
$project->activated_at->format('m/d/Y')?
So, meet Eloquent $casts
and $dates
.
$casts and $dates Properties
For long years in Laravel, there has been a property that you can define on Eloquent models, which fields should be auto-transformed into Carbon objects:
class Project extends Model { protected $dates = [ 'activated_at', 'deactivated_at', // ... ]; }
And then, everywhere you use this value, in Blade or elsewhere, you get a Carbon object and can use it like in the example above: $project->activated_at->format('m/d/Y')
But a bit later, Laravel introduced a more global concept of Casting, auto-transforming any field to any of the available types, and date/time became just one single example of a broader casting topic.
From then, the officially recommended behavior became to auto-Carbon the dates with $casts
property, instead of the older $dates
:
class Project extends Model { protected $casts = [ 'activated_at' => 'date', 'deactivated_at' => 'date', ]; }
Now, the new casting property comes with an additional benefit: you can also provide the format inside the property, like this:
protected $casts = [ 'activated_at' => 'date:m/d/Y', 'deactivated_at' => 'date:m/d/Y',];
It will not auto-transform the $project->activated_at
to the correct format when you access it, but it will do it when you use ->toArray()
or ->toJSON()
methods on the model.
$project->activated_at;// Value: Illuminate\Support\Carbon @1664928000 {#5836// date: 2022-10-05 00:00:00.0 UTC (+00:00),// } $project->toArray()['activated_at'];// Value: 05/10/2022
Since Laravel 11 casts are defined in the casts()
method instead of property.
protected function casts(): array{ return [ 'activated_at' => 'date:m/d/Y', 'deactivated_at' => 'date:m/d/Y', ];}
You can still define casts in a property as it is backward compatible. When an attribute is defined on the property and method, the method one takes priority.
You can read more about date casting in the official docs.
You might also be interested in our PREMIUM course on Dates for Multiple Timezones
Great article.
I like to read articles about simple stuff instead of videos, easier to resume or see code whenever needed.
Thank you so much for this one. I think I like reading now than watching video haha
Thank you