Carbon DiffForHumans: Parameters and Extra Options

Under the hood, Laravel uses the Carbon library for many datetime operations. By default, every created_at/updated_at field in every Model is casted to Carbon objects, so you may write $user->created_at->diffForHumans(). But there are many more possibilities to that method, let's explore them.


Simple Default Example

For those of you who don't know about diffForHumans(): it's a shorter name for "difference for humans". In other words, human-friendly and readable. So, if we run the code above, what would be the result?

1$user = User::factory()->create([
2 'created_at' => now()->subMinutes(5)->subSeconds(10)
3]);
4 
5echo $user->created_at->diffForHumans();
6// Result: "5 minutes ago"

So, instead of showing the datetime as YYYY-MM-DD, you just show a human-friendly text. Cool, isn't it? Now, let's get to extra parameters.


Relative diff

If we compare the time to another time in the past or the future, the result will be different.

1$user = User::factory()->create([
2 'created_at' => now()->addMinutes(5)
3]);
4 
5$user->created_at->diffForHumans();
6// Result: "4 minutes from now"
7// We're running this 1 second later so it's 4:59 left

But if we don't care about which is earlier or later and we need to just know the difference, then we remove the words "from now" or "ago", with this second parameter:

1$user->created_at->diffForHumans(now(), CarbonInterface::DIFF_ABSOLUTE);
2// Result: "4 minutes"

Notice that we do need to provide the first parameter now(), otherwise it wouldn't know what to calculate from. When using the method without parameters, it defaults to now().

The default value of this second parameter is CarbonInterface::DIFF_RELATIVE_AUTO - you need to pass this manually, if you also pass 3rd, 4th and more parameters, see below.


Short Syntax and Locales

Let's go deeper in parameters: the third one is true/false for "short" syntax, default "false". Meaning, instead of "hours", "minutes" and "seconds" you would see "h", "m" and "s":

1$user->created_at->diffForHumans(now(), CarbonInterface::DIFF_RELATIVE_AUTO, true);
2// Result: "4m before"

The official Carbon docs say "3rd parameter to use short syntax if available in the locale used". What does it mean by "locale used"?

By default, Carbon text is returned in English. But you may initialize Carbon from Laravel in other locale.

Example for "5 hours ago":

1$user->created_at->locale('fr')->diffForHumans();
2// Result: "il y a 5 heures"

So yeah, if we pass the locale and set short syntax to true, this is what we get for French language:

1$user->created_at
2 ->locale('fr')
3 ->diffForHumans(now(), CarbonInterface::DIFF_RELATIVE_AUTO, true);
4// Result: "5 h avant"

Notice: I don't speak French, so I can't actually check if it's correct :)

You can also set the locale globally for all your Laravel application, in the config/app.php file, in the "locale" parameter. Then, Carbon will automatically switch to that locale, and you wouldn't need to pass it manually every time.


How Many Parts To Show?

As you saw, for the differens of 4 minutes and 59 seconds, Carbon returns 4 or 5 minutes, without seconds. How to show both?

Actually, you can specify to provide up to six parts of the date to show:

  • years
  • months
  • days
  • hours
  • minutes
  • seconds

For that, you would specify the fourth parameter, which gets the values from 1 to 6.

1$user = User::factory()->create([
2 'created_at' => now()->subYears(2)->subMonths(3)->subDays(5)->subHours(10)
3]);
4 
5$user->created_at->diffForHumans(
6 now(),
7 Carbon\CarbonInterface::DIFF_RELATIVE_AUTO,
8 true,
9 3);
10// Result: "2yrs 3mos 5d before"
11 
12$user->created_at->diffForHumans(
13 now(),
14 Carbon\CarbonInterface::DIFF_RELATIVE_AUTO,
15 true,
16 4);
17// Result: "2yrs 3mos 5d 10h before"
18 
19$user->created_at->diffForHumans(
20 now(),
21 Carbon\CarbonInterface::DIFF_RELATIVE_AUTO,
22 true,
23 6);
24// Result: "2yrs 3mos 5d 10h 16s before"

Array of Options, with More Options

I know what you may be thinking: so many parameters? And, to pass the 4th parameter, we need to pass the 2nd and 3rd default ones?

That's why there's another option: to provide all the settings you want as an array.

1$user->created_at->diffForHumans(['parts' => 4]);
2// Result: "2 years 3 months 5 days 10 hours ago"
3 
4$user->created_at->diffForHumans([
5 'parts' => 4,
6 'join' => ', '
7]);
8// Result: "2 years, 3 months, 5 days, 10 hours ago"
9 
10$user->created_at->diffForHumans([
11 'parts' => 4,
12 'join' => ', ',
13 'short' => true]);
14// Result: "2yrs, 3mos, 5d, 10h ago"

Wait, didn't I mention the "join" option? So yeah, you can provide it to choose the separator, like comma in that case.


This is what I decided to pick out of the official Carbon docs, related to the diffForHumans() method. But there's much more - the full docs page for Carbon is HUGE, so I advise you to plan a few hours and actually read it all. You will find something new, no doubt.

avatar

thank you.

avatar

How would I create the field in the migrate of date and time similar to the automatic timestamp of laravel?. Today I need to change the protected field in the model so that the system understands that it is a date and time.

avatar

I would do it something like $table->timestamp('something_at')->useCurrent();

And then would Cast the Eloquent model's property:

protected $casts = [ 'something_at' => 'datetime' ];

👍 1
avatar

Hi professor, good morning! Thank you very much.

Like our articles?

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

Written by

You might also like