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)
9
  • Does the data come from Database? If so why not sorting via mysql first? Commented Jun 29, 2016 at 8: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: sandbox.onlinephpfunctions.com Commented Jun 29, 2016 at 8:04
  • 2
    String 24/05/2016 00:00:00 can not be converted to datetime, because strtotime expects month first. Use create from format - php.net/manual/en/datetime.createfromformat.php Commented Jun 29, 2016 at 8:04
  • 1
    @DarraghEnright - Its not a duplicate, as that is where I got the 2nd function from Commented Jun 29, 2016 at 8: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. Commented Jun 29, 2016 at 8:06

2 Answers 2

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 :)

Sign up to request clarification or add additional context in comments.

Comments

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?

1 Comment

That does not really answer PO's question

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.