1

I have this array:-

array (size=8)
  0 => 
    array (size=2)
      'date' => string '17/05/2016 00:00:00' (length=19)
      'reason' => string 'DNA' (length=3)
  1 => 
    array (size=2)
      'date' => string '10/05/2016 00:00:00' (length=19)
      'reason' => string 'UTA' (length=3)
  2 => 
    array (size=2)
      'date' => string '03/05/2016 00:00:00' (length=19)
      'reason' => string 'DNA' (length=3)
  3 => 
    array (size=2)
      'date' => string '26/04/2016 00:00:00' (length=19)
      'reason' => string 'true' (length=4)
  4 => 
    array (size=2)
      'date' => string '31/05/2016 00:00:00' (length=19)
      'reason' => string 'true' (length=4)
  5 => 
    array (size=2)
      'date' => string '24/05/2016 00:00:00' (length=19)
      'reason' => string 'true' (length=4)
  6 => 
    array (size=2)
      'date' => string '07/06/2016 00:00:00' (length=19)
      'reason' => string 'true' (length=4)
  7 => 
    array (size=2)
      'date' => string '14/06/2016 00:00:00' (length=19)
      'reason' => string 'true' (length=4)

I want to sort it by 'date'

I tried both of the following methods, but the result ( below )is not sorted correctly.

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

_______________________________
function date_compare($a, $b)
{
    $t1 = strtotime($a['date']);
    $t2 = strtotime($b['date']);
    return $t1 - $t2;
}
usort($course, 'date_compare');

This is the "sorted" array

array (size=8)
  0 => 
    array (size=2)
      'date' => string '24/05/2016 00:00:00' (length=19)
      'reason' => string 'true' (length=4)
  1 => 
    array (size=2)
      'date' => string '14/06/2016 00:00:00' (length=19)
      'reason' => string 'true' (length=4)
  2 => 
    array (size=2)
      'date' => string '31/05/2016 00:00:00' (length=19)
      'reason' => string 'true' (length=4)
  3 => 
    array (size=2)
      'date' => string '26/04/2016 00:00:00' (length=19)
      'reason' => string 'true' (length=4)
  4 => 
    array (size=2)
      'date' => string '17/05/2016 00:00:00' (length=19)
      'reason' => string 'DNA' (length=3)
  5 => 
    array (size=2)
      'date' => string '03/05/2016 00:00:00' (length=19)
      'reason' => string 'DNA' (length=3)
  6 => 
    array (size=2)
      'date' => string '07/06/2016 00:00:00' (length=19)
      'reason' => string 'true' (length=4)
  7 => 
    array (size=2)
      'date' => string '10/05/2016 00:00:00' (length=19)
      'reason' => string 'UTA' (length=3)
Alive to die - Anant
  • 70,531
  • 10
  • 51
  • 98
morne
  • 4,035
  • 9
  • 50
  • 96
  • Does the data come from Database? If so why not sorting via mysql first? – B001ᛦ Jun 29 '16 at 08:03
  • First `usort()` will not work as you are comparing strings, not dates. So you mean `date_compare` function is not working? Use PHPFiddle to provide example: http://sandbox.onlinephpfunctions.com/ – Justinas Jun 29 '16 at 08:04
  • 2
    String `24/05/2016 00:00:00` can not be converted to datetime, because strtotime expects month first. Use create from format - http://php.net/manual/en/datetime.createfromformat.php – splash58 Jun 29 '16 at 08:04
  • 1
    @DarraghEnright - Its not a duplicate, as that is where I got the 2nd function from – morne Jun 29 '16 at 08:05
  • The data does not come directly from the DB, its been handled before ariving to this point so thats why I cant sort on query thanks. – morne Jun 29 '16 at 08:06
  • Yeah - I just realised! Retracted. – Darragh Enright Jun 29 '16 at 08:06
  • Kindly try this link http://stackoverflow.com/questions/16306416/sort-php-multi-dimensional-array-based-on-key – Haseeb Jun 29 '16 at 08:07
  • `array_multisort` is suitable for your case, check out this document, it explain how to use this method clearly http://php.net/manual/en/function.array-multisort.php – Kevin Yan Jun 29 '16 at 08:07
  • @morne can you let me know why you unmarked me? – Alive to die - Anant Jun 29 '16 at 08:51

2 Answers2

4

You need to modify the datetime strings in your $course array in order to make them comparable in the manner that you want.

One (flexible) way to do this is to create DateTime() objects from your datetime strings and compare those.

A quick note about datetimes: standard US format m/d/Y uses forward slashes, and standard European format d-m-Y uses hyphens. Your datetime strings are a mixture of both, using US-style forward slashes with European day/month/year ordering.

Therefore you'll have to take an additional step to parse each datetime string into a valid DateTime() object before comparing.

Static method DateTime::createFromFormat() can help in this regard. For example, given an array called $course:

$course = [
    [
        'date' => '17/05/2016 00:00:00',
        'reason' => 'DNA',
    ],
    [
        'date'   => '10/05/2016 00:00:00',
        'reason' => 'UTA',
    ],
    [
        'date'   => '03/05/2016 00:00:00',
        'reason' => 'DNA',
    ],
    [
        'date'   => '26/04/2016 00:00:00',
        'reason' => 'true',
    ],
    [
        'date'   => '31/05/2016 00:00:00',
        'reason' => 'true',
    ],
    [
        'date'   => '24/05/2016 00:00:00',
        'reason' => 'true',
    ],
    [
        'date'   => '07/06/2016 00:00:00',
        'reason' => 'true',
    ],
    [
        'date'   => '14/06/2016 00:00:00',
        'reason' => 'true',
    ],
];

You can then apply a callback with usort() which converts the date value of each comparison object into a valid DateTime() objects before comparing them:

usort($course, function ($a, $b) {
    $dateA = DateTime::createFromFormat('d/m/Y H:i:s', $a['date']);
    $dateB = DateTime::createFromFormat('d/m/Y H:i:s', $b['date']);
    // ascending ordering, use `<=` for descending
    return $dateA >= $dateB;
});

print_r($course);

This yields:

Array
(
    [0] => Array
        (
            [date] => 26/04/2016 00:00:00
            [reason] => true
        )

    [1] => Array
        (
            [date] => 03/05/2016 00:00:00
            [reason] => DNA
        )

    [2] => Array
        (
            [date] => 10/05/2016 00:00:00
            [reason] => UTA
        )

    [3] => Array
        (
            [date] => 17/05/2016 00:00:00
            [reason] => DNA
        )

    [4] => Array
        (
            [date] => 24/05/2016 00:00:00
            [reason] => true
        )

    [5] => Array
        (
            [date] => 31/05/2016 00:00:00
            [reason] => true
        )

    [6] => Array
        (
            [date] => 07/06/2016 00:00:00
            [reason] => true
        )

    [7] => Array
        (
            [date] => 14/06/2016 00:00:00
            [reason] => true
        )

)

If your course array is very large, then there may be some overhead in creating DateTime objects on the fly like the example above. YMMV. In this case, I'd consider mapping over the array first and create DateTime objects for each entry, and then apply usort().

Note that, with a standard format datetime string, such as European d-m/Y H:i:s, US m/d/Y H:i:s or IS08601 Y-m-d H:i:s, you can simply pass the datetime string as the first value into the DateTime constructor instead; e.g:

$dt = new DateTime($someStandardFormatDateTimeString);

Apologies about the errant close vote earlier. I've removed that now.

Hope this helps :)

Darragh Enright
  • 13,676
  • 7
  • 41
  • 48
0

Create a new array and use the index and unix timestamp then it should be a simple asort

$unix_time = date('Ymdhis', strtotime($datetime ));

PHP asort

How do I get a unix timestamp from PHP date time?

Community
  • 1
  • 1
bluepinto
  • 165
  • 9