A tutorial for grouping a collection of data by date (day, month and year) in a Laravel project.

🌍 The French version of this publication : Comment grouper une collection par jour, mois et année dans Laravel

A collection in the PHP Laravel framework is a class that can be used to manipulate data sets. It provides methods for working with data arrays and objects, enabling them to be filtered, grouped, sorted and manipulated efficiently.

In this tutorial, we'll look at how to group the data in a collection into days, months and years. To do this, we'll use the collection's groupBy() method and the Carbon library's format() method for manipulating dates and times.

Let's consider a collection of users App\Models\User.php that we can obtain using the following instruction:

$users = User::all(); // The users' collection

// $users = User::orderBy("created_at")->get(); // The collection of users ordered by the "created_at" field

For each user, we have a timestamp creation date (created_at) which we can use to group the data in the collection according to a date format:

$users_grouped = $users->groupBy(function ($item, $key) {

    return $item->created_at->format('d-m-Y');

});

In this source code, we have :

  1. The groupBy() method, which groups the elements of the collection. It takes an anonymous function as parameter, giving access to each element or $item in the collection.
  2. For each $item, we format the created_at date in d-m-Y (day-month-year) using the format() method. Accepted formats are described in the datetime documentation.

📄 Please note: The created_at and updated_at attributes of Laravel models are Illuminate\Support\Carbon objects by default. If you're using another time field in your model and want to exploit it and treat it as a Carbon object, you can convert it using the model's $casts property :

protected $casts = [
    "example_date" => "datetime",
];

Finally, we can display the collection grouped by date in a Blade view as follows:

<ul>
@foreach ($users_grouped as $date_group)
	<li>
		{{ $date_group->first()->created_at->format('d-m-Y') }}
		<ul>
		@foreach ($date_group as $user)
			<li>{{ $user->name }}</li>
		@endforeach
		</ul>
	</li>
@endforeach
</ul>

Here is an example of what this source code can display in the browser:

Une liste de noms ordonnée par date

Take care of yourself 😎