Laravel Datetime to Carbon Automatically: $dates or $casts

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:

1Carbon::createFromFormat('Y-m-d', $project->activated_at)
2 ->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?

1$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:

1class Project extends Model {
2 
3 protected $dates = [
4 'activated_at',
5 'deactivated_at',
6 // ...
7 ];
8 
9}

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:

1class Project extends Model {
2 
3 protected $casts = [
4 'activated_at' => 'date',
5 'deactivated_at' => 'date',
6 ];
7 
8}

Notice: the older $dates property also still works, at least at the time of writing this article.

Now, the new casting property comes with an additional benefit: you can also provide the format inside the property, like this:

1protected $casts = [
2 'activated_at' => 'date:m/d/Y',
3 'deactivated_at' => 'date:m/d/Y',
4];

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.

1$project->activated_at;
2// Value: Illuminate\Support\Carbon @1664928000 {#5836
3// date: 2022-10-05 00:00:00.0 UTC (+00:00),
4// }
5 
6$project->toArray()['activated_at'];
7// Value: 05/10/2022

You can read more about date casting in the official docs.

avatar

Great article.

I like to read articles about simple stuff instead of videos, easier to resume or see code whenever needed.

Like our articles?

Become a Premium Member for $129/year or $29/month

Written by

Recent Premium Tutorials