Laravel sort collection by date
Stefan Bogdanescu
Founder & Senior Architect · 2026-06-29
Title: Sorting Collections by Date with Laravel - A Comprehensive Guide
Body:
Handling date-based collections in your Laravel application can be challenging, especially when dealing with data spanning across multiple months. In this post, we'll tackle the issue of sorting a collection by date and provide you with all necessary information to ensure the process goes smoothly.
Firstly, let us take a look at the initial problem statement:$result = [{
"date": "2016-03-21",
"total_earned": "101214.00"
},
{
"date": "2016-03-22",
"total_earned": "94334.00"
},
{
"date": "2016-03-23",
"total_earned": "96422.00"
},
{
"date": "2016-02-23",
"total_earned": 0
},
{
"date": "2016-02-24",
"total_earned": 0
},
{
"date": "2016-02-25",
"total_earned": 0
}]
We want to sort the collection by date, but our current implementation doesn't seem to be working as expected:
$sorted = $transaction->sortBy('date')->values()->all();
[{
"date": "2016-02-23",
"total_earned": 0
},
{
"date": "2016-02-24",
"total_earned": 0
},
{
"date": "2016-02-25",
"total_earned": 0
},
{
"date": "2016-03-22",
"total_earned": "94334.00"
},
{
"date": "2016-03-21",
"total_earned": "101214.00"
},
{
"date": "2016-03-23",
"total_earned": "96422.00"
}]
As you can see, the sorting is working fine for the February dates, but it begins to behave strangely at the beginning of March.
The reason behind this issue lies in Laravel's default sorting behavior. By default, Laravel uses the natural order of the string values to sort the collection. In our case, because the date format is "yyyy-mm-dd", Laravel will first sort by year, then by month number (as a numeric value), and finally by day. This creates a problem when dealing with months that contain both dates within different years or months with no zero padding for the day numbers.
To solve this issue, we can use a custom comparator function to provide Laravel with a specific sorting order based on our requirements. Here's an example:
$sorted = $transaction->sort(function ($a, $b) {
if (strtotime($a['date']) == strtotime($b['date'])) {
return 0;
}
// Sort by year first, descending.
if (strtotime($a['date']) < strtotime($b['date'])) {
return -1;
} else if (strtotime($a['date']) > strtotime($b['date'])) {
return 1;
}
// If years are the same, sort by month and day.
$aMonth = date('n', strtotime($a['date']));
$bMonth = date('n', strtotime($b['date']));
if ($aMonth == $bMonth) {
return 0;
}
// If months are the same, sort by day.
if (strtotime($a['date']) < strtotime($b['date'])) {
return -1;
} else if (strtotime($a['date']) > strtotime($b['date'])) {
return 1;
}
});
This code will ensure a more accurate sorting when working with collections containing dates in various formats and scenarios. Remember to adjust the conditionals based on your specific needs, such as if you prefer ascending order or want to prioritize different aspects of the date.
In conclusion, this blog post has explained how to tackle the issue of sorting a collection by date using Laravel's default sorting behavior and a custom comparator function. By understanding the underlying principles, developers can ensure they achieve accurate and reliable results with their collections.