27

How can I re-arrange an array of objects like this:

 [495] => stdClass Object
        (
         [date] => 2009-10-31 18:24:09
         ...
        )
 [582] => stdClass Object
        (
         [date] => 2010-2-11 12:01:42
         ...
        )
 ...

by the date key, oldest first?

0

6 Answers 6

55
usort($array, function($a, $b) {
    return strtotime($a['date']) - strtotime($b['date']);
});

Or if you don't have PHP 5.3:

function cb($a, $b) {
    return strtotime($a['date']) - strtotime($b['date']);
}
usort($array, 'cb');
Sign up to request clarification or add additional context in comments.

2 Comments

Looks good, and I'd recommend to the OP to do the date/time sorting in the database, and/or return a plain unix timestamp along with the formatted value, as strtotime() has CONSIDERABLE overhead and would make repeated sorting very expensive.
replace usort by uasort then
25

Since the original question is about sorting arrays of stdClass() objects, here's the code which would work if $a and $b are objects:

usort($array, function($a, $b) {
    return strtotime($a->date) - strtotime($b->date);
});

Or if you don't have PHP 5.3:

function cb($a, $b) {
    return strtotime($a->date) - strtotime($b->date);
}
usort($array, 'cb');

2 Comments

working great, thank yu
Glad to read that after 12 long years ;)
3

I wanted to expand on arnaud576875's answer. I ran across this same issue, but with using DateTime objects. This is how I was able to accomplish the same thing.

usort($array, function($a, $b) {
    return $a['date']->format('U') - $b['date']->format('U');
});

1 Comment

Are you calling the format() method on a string value? This answer feels misleading to researchers. The OP's sample data is an array of objects, not an array of arrays.
2

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.

Comments

0

I wanted to expand on arnaud576875 and Michael Irigoyen.

Same issue with object containing dateTime with Symphony.

I coudn't use $a['date'] because it was not an key array.

usort($verifications, function($a, $b) {
   return $a->getDate()->format('U') - $b->getDate()->format('U');
});

This solved my problem

Comments

0

When working with DateTime objects as properties of your Entity, this worked for me:

$myArray = $entityRepository->findAll();

usort($myArray, function($a, $b) {
    return $a->getDate()->getTimestamp() - $b->getDate()->getTimestamp();
        });

1 Comment

Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.