Sort Array by Date in Descending Order by Date in PHP

How to sort an array by date field descending order?

As said in the comments, the core issue here is that strtotime doesn't understand your date time format. You could have figured that out by looking at the return value, which is FALSE if conversion fails.

So, the solution is to use another function to do the conversion, eg date_create_from_format and extract the epoch second value from that DateTime using date_timestamp_get to compare those, like this:

usort($tbData, function ($a, $b) {
$sa = date_create_from_format('d M, Y H:i a',$a[2]);
$sb = date_create_from_format('d M, Y H:i a',$b[2]);
return date_timestamp_get($sa) - date_timestamp_get($sb);
});

How to sort date array in php?

If the date is in "Mysql" format (Y-m-d or Y-m-d H:i:s), then you can sort your array right away, no special action needed:

$arr = ["2019-11-11", "2019-10-10","2019-11-11", "2019-09-08","2019-05-11"];
sort($arr);

If the date is localized or formatted anyhow (that you should avoid, formatting the date only before output) you have to use a custom sorting function, such as usort(), that will convert the dates into sortable format before comparison.

The simplest way to convert a date into sortable format is to convert it into uninx timestamp using strtotime() function:

$arr = ['11/01/2012', '03/16/2022', '12/26/2021', '01/01/2014', '09/02/2013'];
usort($arr, function ($a, $b) {
return strtotime($a) - strtotime($b);
});
print_r($arr);

Check result in demo

However, there could be pitfalls, because in different countries the same date format could mean a different date. Which is exactly the case with your example format, for which the above function will return wrong results if dates are ['03-16-2022', '12-26-2021', '06-06-2022']. Therefore it's better to define the date format explicitly, as explained in this answer

Sort dates before today in ascending order and after today in descending order

This is a job for usort() with a comparison function you provide.

Your comparison function gets called like cmp($a, $b). $a and $b are two items from your array. If $a goes before $b in the output, you return -1. If $a goes after $b, return 1. If they're the same return 0. So, you'll need a comparision function implementing your specific before / after logic.

The usort() function calls your comparison function whenever it needs to compare one date with another to do your sort. It calls your function O(n log(n)) times with different pairs of values.

Something like this? NOT, repeat NOT, debugged.

$nowTimeForMySort = time();

function cmpDates ($a, $b) {
global $nowTimeForMySort;
/* equal times, return 0 */
if ($a == $b) return 0;

$aTime = strtotime($a);
$bTime = strtotime($b);

/* if one date is in the past and the other in the future,
* always put the date in the past before the date in the future. */
if ($aTime <= $nowTimeForMySort && $bTime > $nowTimeForMySort) return -1;
if ($aTime > $nowTimeForMySort && $bTime <= $nowTimeForMySort) return 1;

/* when we get here, both dates are either past or future. */
if ($aTime <= $nowTimeForMySort) {
/* past dates: ascending */
if ($aTime < $bTime) return -1;
if ($aTime > $bTime) return 1;
} else {
/* future dates: descending */
if ($aTime < $bTime) return 1;
if ($aTime > $bTime) return -1;
}
return 0;
}

Then use that function in usort() like this.

usort($a, 'cmpDates');

Pro tip: You must be absolutely sure that your comparison function's output depends only, deterministically, on its two inputs and not on anything that might change. That's why this example stuffs the current time into a global variable: we don't want the time to change while the sort is in progress or the results might be very strange.

Pro tip Some languages' comparison functions allow the return of negative / zero / positive numbers. php's requires you to return -1, 0, 1.

PHP Sort a multidimensional array by element containing Y-m-d H:i:s date

Use usort() and a custom comparison function:

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

EDIT: Your data is organized in an array of arrays. To better distinguish those, let's call the inner arrays (data) records, so that your data really is an array of records.

usort will pass two of these records to the given comparison function date_compare() at a a time. date_compare then extracts the "datetime" field of each record as a UNIX timestamp (an integer), and returns the difference, so that the result will be 0 if both dates are equal, a positive number if the first one ($a) is larger or a negative value if the second argument ($b) is larger. usort() uses this information to sort the array.

Order a array by date in Laravel

Assuming $testimonials is a collection object, you can make use of sortByDesc() to sort by dates in decreasing order.

<?php 

$testimonials = $testimonials->sortByDesc(function($a){
return DateTime::createFromFormat('d/m/Y',$a['date']);
});

dd($testimonials);

Sort array by date, then by time - PHP

As @Don't Panic says, if you can do the sorting as part of your database request go for that.

Otherwise, if you are stuck with the array as is - you can extract the data from the date and start strings, put it in the correct order, then use strcmp() when you sort. For example,

usort($booking, function($a, $b) {
// extract year, month and day from date
list($a_month, $a_day, $a_year) = explode('/', $a['date']);
list($b_month, $b_day, $b_year) = explode('/', $b['date']);
// compare the correctly ordered strings
return strcmp($a_year.$a_month.$a_day.$a['start'], $b_year.$b_month.$b_day.$b['start']);
});

Some reference if some of the code is unfamiliar

strcmp() http://php.net/manual/en/function.strcmp.php

list() http://php.net/manual/en/function.list.php

Sort array of objects by closest date

What you need to do is work out how far each date is away from today and use this to sort the items, there may be a more elegant way, but this (I think) works. Basically use abs() to ensure all differences are +ve and take each date away from today...

usort($arr, function($a, $b) {
return (abs(strtotime('today') - strtotime($a->date))
- (abs(strtotime('today') - strtotime($b->date))));
});


Related Topics



Leave a reply



Submit