9

I have an array and I want to sort it by date. I am not able to sort it properly by date in descending order. Please help.

Array
(
[1] => Array
    (
        [1] => 11/05/2013
        [2] => Executive Planning Day
    )

[2] => Array
    (
        [1] => 13/06/2013
        [2] => Middle Leaders Planning Day
    )

[3] => Array
    (
        [1] => 12/07/2013
        [2] => New Staff Induction Day
    )

[4] => Array
    (
        [1] => 13/04/2013
        [2] => Staff Conference Day No. 1
    )

[5] => Array
    (
        [1] => 14/04/2013
        [2] => Staff Conference Day No. 2
    )

[6] => Array
    (
        [1] => 15/02/2013
        [2] => Staff Conference Day No. 3
    )

[7] => Array
    (
        [1] => 16/03/2013
        [2] => Australia Day
    )
)
Baba
  • 94,024
  • 28
  • 166
  • 217
Neeraj Sharma
  • 346
  • 1
  • 4
  • 16
  • Maby have a look at this thread: http://stackoverflow.com/questions/96759/how-do-i-sort-a-multidimensional-array-in-php – Eernie May 24 '13 at 11:03

11 Answers11

22

Try like this

function sortFunction( $a, $b ) {
    return strtotime($a[1]) - strtotime($b[1]);
}
usort($data, "sortFunction");   //Here You can use asort($data,"sortFunction")

or you may try by detail like(its just suggestion)

function sortFunction($a,$b)
    if ($a[1] == $b[1]) return 0;
    return strtotime($a[1]) - strtotime($b[1]);
}
usort($data,"sortFunction");

As the strtotime is not obey d/m/Y format try like this

$orderByDate = $my2 = array();
foreach($data as $key=>$row)
{
    $my2 = explode('/',$row[1]);
    $my_date2 = $my2[1].'/'.$my2[0].'/'.$my2[2];        
    $orderByDate[$key] = strtotime($my_date2);  
}    
array_multisort($orderByDate, SORT_DESC, $data);
GautamD31
  • 28,552
  • 10
  • 64
  • 85
3

I spent a night working on how to do this for my own similar issue. To sort an associative array by date of a key in that array.

Both usort and uasort require a sort function that you must write and pass as the second parameter. The sort function is used by usort and uasort to compare each item in the array and store the result as $yourArray

 function sortFunction( $a, $b ) {
           return strtotime($a[1]) - strtotime($b[1]);
 }

 uasort($yourArray, "sortFunction");
jmontross
  • 3,533
  • 1
  • 21
  • 17
2

Use usort(Sort an array by values using a user-defined comparison function).

usort($array, function($a1, $a2) {
   $value1 = strtotime($a1['date']);
   $value2 = strtotime($a2['date']);
   return $value1 - $value2;
});
Vivek Sadh
  • 4,230
  • 3
  • 32
  • 49
  • getting incorrect data after using your suggestions : Array ( [0] => Array ( [1] => 11/05/2013 [2] => Middle Leaders ) [1] => Array ( [1] => 10/05/2013 [2] => Executive Planning Day ) [3] => Array ( [1] => 25/06/2013 [2] => New Staff Induction Day ) [4] => Array ( [1] => 27/06/2013 [2] => Year 8-12 commence ) [6] => Array ( [1] => 23/06/2013 [2] => Executive Planning Day )} – Neeraj Sharma May 24 '13 at 11:18
  • I have tried all the suggestions but data is not coming in properly descending order. – Neeraj Sharma May 24 '13 at 11:19
2

Use usort() function:

function cmp($a, $b) {
    if ($a[1] == $b[1]) return 0;
    return (strtotime($a[1]) < strtotime($b[1])) ? 1 : -1;
}

usort($data, "cmp");
Vedran Šego
  • 3,553
  • 3
  • 27
  • 40
  • getting incorrect data after using your suggestions : Array ( [0] => Array ( [1] => 11/05/2013 [2] => Middle Leaders ) [1] => Array ( [1] => 10/05/2013 [2] => Executive Planning Day ) [3] => Array ( [1] => 25/06/2013 [2] => New Staff Induction Day ) [4] => Array ( [1] => 27/06/2013 [2] => Year 8-12 commence ) [6] => Array ( [1] => 23/06/2013 [2] => Executive Planning Day )} – Neeraj Sharma May 24 '13 at 11:25
  • @neerajsharma Your dates are not in [proper format](http://www.php.net/manual/en/datetime.formats.date.php). You can replace that by a `preg_match()`. However, it might be more time-efficient to go once through `$data` and add a timestamp to each item before sortin, so that this conversion is done only once per item. – Vedran Šego May 24 '13 at 12:42
2

Not entirely happy with all of the answers here so I thought I'd mention that if you wish to sort an associative array preserving the keys then you should use uasort rather than usort. You can also parse the date from any format you like with the DateTime library which also includes some predefined constants for some of the standard formats.

uasort($array, function($a, $b){ 
    $format = 'd/m/Y'; 
    $ascending = false;
    $zone = new DateTimeZone('UTC');
    $d1 = DateTime::createFromFormat($format, $a[1], $zone)->getTimestamp();
    $d2 = DateTime::createFromFormat($format, $b[1], $zone)->getTimestamp();
    return $ascending ? ($d1 - $d2) : ($d2 - $d1);
});

demo

Emissary
  • 9,954
  • 8
  • 54
  • 65
2

I jumped here for associative array sorting and found this amazing function on http://php.net/manual/en/function.sort.php. This function is very dynamic that sort in ascending and descending order with specified key.

Simple function to sort an array by a specific key. Maintains index association.

<?php

function array_sort($array, $on, $order=SORT_ASC)
{
    $new_array = array();
    $sortable_array = array();

    if (count($array) > 0) {
        foreach ($array as $k => $v) {
            if (is_array($v)) {
                foreach ($v as $k2 => $v2) {
                    if ($k2 == $on) {
                        $sortable_array[$k] = $v2;
                    }
                }
            } else {
                $sortable_array[$k] = $v;
            }
        }

        switch ($order) {
            case SORT_ASC:
                asort($sortable_array);
            break;
            case SORT_DESC:
                arsort($sortable_array);
            break;
        }

        foreach ($sortable_array as $k => $v) {
            $new_array[$k] = $array[$k];
        }
    }

    return $new_array;
}

$people = array(
    12345 => array(
        'id' => 12345,
        'first_name' => 'Joe',
        'surname' => 'Bloggs',
        'age' => 23,
        'sex' => 'm'
    ),
    12346 => array(
        'id' => 12346,
        'first_name' => 'Adam',
        'surname' => 'Smith',
        'age' => 18,
        'sex' => 'm'
    ),
    12347 => array(
        'id' => 12347,
        'first_name' => 'Amy',
        'surname' => 'Jones',
        'age' => 21,
        'sex' => 'f'
    )
);

print_r(array_sort($people, 'age', SORT_DESC)); // Sort by oldest first
print_r(array_sort($people, 'surname', SORT_ASC)); // Sort by surname
Ahmad Sayeed
  • 344
  • 2
  • 14
1

I'd build an array for ordering.

$ordered = array();
foreach ($planning as $event) {
  $ordered[$event['date']] = $event;
}
ksort($ordered);
Ven
  • 19,015
  • 2
  • 41
  • 61
1

so do it like this:

//your array


$arr = array();
array_push($arr, array("11/05/2013", "Executive Planning Day"));
array_push($arr, array("13/06/2013", "Middle Leaders Planning Day"));
array_push($arr, array("12/07/2013", "New Staff Induction Day"));
array_push($arr, array("13/04/2013", "Staff Conference Day No. 1"));
array_push($arr, array("14/04/2013", "Staff Conference Day No. 2"));
array_push($arr, array("15/02/2013", "Staff Conference Day No. 3"));
array_push($arr, array("16/03/2013", "Australia Day"));


var_dump($arr);

function sortDateDesc($a, $b){  
    $strA = implode("-", array_reverse( explode("/", $a[0]) ) ); 
    $strB = implode("-", array_reverse( explode("/", $b[0]) ) ); 

    return strtotime($strB) - strtotime($strA);
}



usort($arr, "sortDateDesc");

var_dump($arr);

If your date format is constant day/month/year then you need to pass it in a string format recognized by the parser and year-month-day is an ISO standard if I remember it well, that one works fine

Sagan
  • 112
  • 1
  • 7
1

Here is a working example with the spaceship operator <=>

    $array = Array(
        Array(
            "id" => "1",
            "date_time_rdv" => "2018-02-22 11:29:35",
        ),
        Array(
            "id" => "2",
            "date_time_rdv" => "2020-02-13 10:05:25",
        ),
        Array(
            "id" => "3",
            "date_time_rdv" => "2019-02-15 22:18:45",
        )
    );

    function date_compare($a, $b) {
        $format = 'Y-m-d H:i:s';
        $d1 = DateTime::createFromFormat($format, $a['date_time_rdv']);
        $d2 = DateTime::createFromFormat($format, $b['date_time_rdv']);
        return $d2 <=> $d1;
    }

    usort($array, 'date_compare');

It will output :

Array
(
    [0] => Array
        (
            [id] => 2
            [date_time_rdv] => 2020-02-13 10:05:25
        )

    [1] => Array
        (
            [id] => 3
            [date_time_rdv] => 2019-02-15 22:18:45
        )

    [2] => Array
        (
            [id] => 1
            [date_time_rdv] => 2018-02-22 11:29:35
        )

)

If you use uasort() instead, it will output this (it will maintain index association)

Array
(
    [1] => Array
        (
            [id] => 2
            [date_time_rdv] => 2020-02-13 10:05:25
        )

    [2] => Array
        (
            [id] => 3
            [date_time_rdv] => 2019-02-15 22:18:45
        )

    [0] => Array
        (
            [id] => 1
            [date_time_rdv] => 2018-02-22 11:29:35
        )

)

If you try return $d1 <=> $d2;, it will reverse the order.

In date_compare(), we use DateTime::createFromFormat which parses a time string according to a specified format. You could use the format you need, like in the op question dd/mm/YYYY

More info on DateTime::createFromFormat :

Sébastien Gicquel
  • 4,227
  • 7
  • 54
  • 84
0

The solution of @Gautam3164 is almost perfect. You need to change the format of the dates. I'd say:

function sortFunction( $a, $b ) {
    return strtotime(str_replace('/', '-',$a[1])) - strtotime(str_replace('/', '-',$b[1]));
}
usort($data, "sortFunction");   //Here You can use asort($data,"sortFunction")

11/10/1987 -> 10 Nov 1987 11-10-1987 -> 11 Oct 1987

JokiRuiz
  • 311
  • 3
  • 12
0
$sortdate = array(
    '17/08/2015',
    '02/01/2017',
    '05/02/2014'
);

function sortFunction($a, $b)
    {
    $datea = strtotime(str_replace('/', '-', $a));
    $dateb = strtotime(str_replace('/', '-', $b));
    if ($datea == $dateb)
        {
        return 0;
        }

    return ($datea < $dateb) ? -1 : 1;
    }

usort($sortdate, "sortFunction");
echo "<pre>";
var_dump($sortdate);