Because your month -- and possibly your day -- values are not zero-padded, you cannot instantly compare the dates as simple strings. You should use strtotime()
to convert the dates to unix time integers -- these will be suitable for reliable comparisons.
Also, it seems important to not lose the associative relationship between the first level keys and their objects. To sort and retain the keys, call uasort()
. In modern php, the spaceship operator is the go-to utility for making 3-way comparisons (returns -1, 0, or 1).
All approaches below will work identically even if the 2d array is an array of arrays instead of an array of objects (you'll only need to change the ->date
syntax to ['date']
.
Code:
uasort(
$array,
function($a, $b) {
return strtotime($a->date) <=> strtotime($b->date);
}
);
Or in PHP7.4, there is arrow function syntax:
uasort(
$array,
fn($a, $b) => strtotime($a->date) <=> strtotime($b->date)
);
The only minor drawback with using function calls in u*sort()
's body is that it will do greater than n sets of function calls to break ties and otherwise determine the correct order. An alternative sorting technique that avoids these redundant function calls is array_multisort()
. It can be fed a column of data which has had exactly n function calls performed -- this effectively makes it more efficient. However, this sorting function has its own caveat -- it will lose the numeric first level keys. This is probably not a tolerable loss for this case.
Code:
array_multisort(
array_map('strtotime', array_column($array, 'date')),
$array
);
Here is a demo of both techniques.
For anyone who is sorting date, time, or datetime values that can be naturally compared as basic strings (so-called Big-endian formats such as Y-m-d H:i:s
, H:i
, m/d
, Y-m-d
, etc., then see this answer for more efficient techniques.