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.
sort multidimensional array by date
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 :)
How to sort multidimensional array by date?
Use uksort. You can make your own compare function. There you could convert key into timestamp and compare.
You can change order direction
return $a > $b; // order ASC
return $a < $b; // order DESC
Your code should look like:
function cmp($a, $b)
{
$a = strtotime($a);
$b = strtotime($b);
return $a > $b;
}
uksort($data, "cmp");
See DEMO
OUTPUT
Array
(
[September 2, 2015] => Array
(
[admin] => Array
(
[checkin] => 2
[checkout] => 1
)
)
[September 3, 2015] => Array
(
[admin] => Array
(
[checkin] => 2
[checkout] => 2
)
)
[September 4, 2015] => Array
(
[admin] => Array
(
[checkin] => 1
[checkout] => 1
)
)
[September 5, 2015] => Array
(
[admin] => Array
(
[checkin] => 1
[checkout] => 1
)
)
[September 6, 2015] => Array
(
[admin] => Array
(
[checkin] => 2
[checkout] => 2
)
)
[September 7, 2015] => Array
(
[admin] => Array
(
[checkin] => 1
[checkout] => 1
)
)
[September 8, 2015] => Array
(
[admin] => Array
(
[checkin] => 1
[checkout] => 0
)
)
[October 8, 2015] => Array
(
[admin] => Array
(
[checkin] => 1
[checkout] => 0
)
)
)
How to sort a 3 dimensional array by element containing date, from newest to oldest
You can do this as a two-stage process. First, use array_walk
with array_multisort
to sort the inner arrays by datetime
. Then use usort
, comparing the maximum datetime
values from the inner arrays:
array_walk($arr, function (&$v) { array_multisort(array_column($v, 'datetime'), SORT_DESC, $v); });
usort($arr, function ($a, $b) {
return strcmp(max(array_column($b, 'datetime')), max(array_column($a, 'datetime')));
});
print_r($arr);
Output:
Array
(
[0] => Array
(
[0] => Array
(
[personNum] => 4
[type] => status
[datetime] => 2019-05-26 16:04:24
)
[1] => Array
(
[personNum] => 3
[type] => status
[datetime] => 2019-05-26 15:59:53
)
)
[1] => Array
(
[0] => Array
(
[personNum] => 3
[type] => status
[datetime] => 2019-05-26 15:59:53
)
[1] => Array
(
[personNum] => 2
[type] => comment
[datetime] => 2019-05-15 11:29:45
)
)
)
Demo on 3v4l.org
Sort multidimensional array according to date values in in two elements?
I'm not sure if understood correctly but you mean you want sort your array base on column1 ("post date") and if these values are equal order is determined by column2. So, what you need is just fix your comparing function:
function date_compare($a, $b)
{
$t1 = strtotime($a['datetime']);
$t2 = strtotime($b['datetime']);
if ($t1 != $t2) {
return $t1 - $t2;
}
// if "post dates" are equal, compare "edit dates"
$t1 = strtotime($a['datetime2']);
$t2 = strtotime($b['datetime2']);
return $t1 - $t2;
}
edit:
ok, according to your comment, you just need to pick up max element from your array. So, this should work:
usort($array, function($a, $b) {
$t1 = max(strtotime($a[0]), strtotime($a[1]));
$t2 = max(strtotime($b[0]), strtotime($b[1]));
return $t1 - $t2;
});
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
Related Topics
PHP + MySQL Transactions Examples
Fatal Error: Uncaught Error: Call to Undefined Function MySQL_Connect()
Delimiter Must Not Be Alphanumeric or Backslash and Preg_Match
How to Change From-address When Using Gmail Smtp Server
I Have 2 Dates in PHP, How to Run a Foreach Loop to Go Through All of Those Days
PHP File_Get_Contents() and Setting Request Headers
Make All Words Lowercase and the First Letter of Each Word Uppercase
How to Convert an Object to an Array
PHP How to Find the Time Elapsed Since a Date Time
PHP File_Get_Contents() Returns "Failed to Open Stream: Http Request Failed!"
How to Implement Authorization Using a Telegram API
Access a JavaScript Variable from PHP
How to Use MySQLi Prepared Statements
How to Convert a Pdf Document to a Preview Image in PHP
"Date(): It Is Not Safe to Rely on the System'S Timezone Settings..."