2

I have a long multi dimensional array including some DateTime objects. I want to sort the entire array based on the [startdate] object. I'm using this usort function (based on a lot of online resources and modifications from various errors). It's not sorting the array.

My array is formatted as follows. Showing only the start for brevity.

Array
(
    [] => Array
        (
            [startdate] => DateTime Object
                (
                    [date] => 2019-04-10 19:00:00.000000
                    [timezone_type] => 3
                    [timezone] => America/New_York
                )

            [starttime] => DateTime Object
                (
                    [date] => 2019-04-10 19:00:00.000000
                    [timezone_type] => 3
                    [timezone] => America/New_York
                )

Here is my usort code:

function date_compare($a, $b) {
    $t1 = $a["startdate"]->format('Y-m-d H:i:s');
    $t2 = $b["startdate"]->format('Y-m-d H:i:s');           
    return $t1 - $t2;
}    
usort($allEventsSimple, 'date_compare');

I also tried sorting the DateTime objects using this code:

function date_compare($a, $b) {
    $t1 = var_dump($a[startdate]);
    $t2 = var_dump($b[startdate]);          
    return $t1 - $t2;
}    
usort($allEventsSimple, 'date_compare');
Amy
  • 165
  • 1
  • 10
  • 1
    Just do `strtotime($a["date"]) - strtotime($b["date"])`. You will also need to loop over the elements of the base array. – Aniket Sahrawat Apr 05 '19 at 03:14
  • @AniketSahrawat the `startdate` values are `DateTime` instances. You cannot use those in `strtotime()`, it will throw an error ~ _"PHP Warning: strtotime() expects parameter 1 to be string, object given"_ – Phil Apr 05 '19 at 03:18
  • This is giving me the error: Warning: strtotime() expects parameter 1 to be string, object given. – Amy Apr 05 '19 at 03:21
  • 2
    Missed that, try `strtotime($a['startdate']->date) - strtotime($b['startdate']->date)` @AmyMcGarity-GermanPearls – Aniket Sahrawat Apr 05 '19 at 03:21
  • 1
    `$dateObj->getTimestamp()` – Beginner Apr 05 '19 at 03:22
  • 1
    @Beginner I can't see `getTimestamp` in the dump, it might not work. –  Apr 05 '19 at 03:23
  • @roundAbout it's a method of `DateTime` ~ https://www.php.net/manual/datetime.gettimestamp.php – Phil Apr 05 '19 at 03:24
  • @AniketSahrawat there is no `date` property of [`DateTime`](https://www.php.net/manual/class.datetime.php) – Phil Apr 05 '19 at 03:25
  • @Phil I understand that it's a method which is inherited from `DateTime` but I don't think it is present in the above case. –  Apr 05 '19 at 03:26
  • 1
    @AmyMcGarity-GermanPearls https://www.php.net/manual/en/datetime.gettimestamp.php – Beginner Apr 05 '19 at 03:26
  • @roundAbout it totally is. See where it says `[startdate] => DateTime Object`? That's saying the value of that array key is an instance of `DateTime`. What you're seeing underneath that is just the debugging properties – Phil Apr 05 '19 at 03:28
  • 2
    @Phil I can see a field named `date` in `startdate`. – Aniket Sahrawat Apr 05 '19 at 03:29
  • @AniketSahrawat you're right (demo https://3v4l.org/iMHUP). Not sure why but my local PHP version (PHP 7.2.15-0ubuntu0.18.04.2) complains if I try and use it. Perhaps because it's undocumented – Phil Apr 05 '19 at 03:32
  • @Beginner getTimestamp() worked - thanks! – Amy Apr 05 '19 at 03:55

1 Answers1

2

You actually do have errors, you just can't see them (see How to get useful error messages in PHP?)

Your code would be producing

PHP Notice: A non well formed numeric value encountered in ...

This is because you're attempting to subtract one non-numeric string from another.

If you're using PHP 7, you can directly compare DateTime instances with the awesomely named "spaceship operator", eg

return $a['startdate'] <=> $b['startdate'];

enter image description here


If you're stuck on PHP 5, compare timestamps

return $a['startdate']->getTimestamp() - $b['startdate']->getTimestamp();
Phil
  • 157,677
  • 23
  • 242
  • 245