Reputation: 346
I have an array and I want to sort it by date. I am not able to sort it properly by date in descending order. Please help.
Array
(
[1] => Array
(
[1] => 11/05/2013
[2] => Executive Planning Day
)
[2] => Array
(
[1] => 13/06/2013
[2] => Middle Leaders Planning Day
)
[3] => Array
(
[1] => 12/07/2013
[2] => New Staff Induction Day
)
[4] => Array
(
[1] => 13/04/2013
[2] => Staff Conference Day No. 1
)
[5] => Array
(
[1] => 14/04/2013
[2] => Staff Conference Day No. 2
)
[6] => Array
(
[1] => 15/02/2013
[2] => Staff Conference Day No. 3
)
[7] => Array
(
[1] => 16/03/2013
[2] => Australia Day
)
)
Upvotes: 9
Views: 57942
Reputation: 4386
Here is a working example with the spaceship operator <=>
$array = Array(
Array(
"id" => "1",
"date_time_rdv" => "2018-02-22 11:29:35",
),
Array(
"id" => "2",
"date_time_rdv" => "2020-02-13 10:05:25",
),
Array(
"id" => "3",
"date_time_rdv" => "2019-02-15 22:18:45",
)
);
function date_compare($a, $b) {
$format = 'Y-m-d H:i:s';
$d1 = DateTime::createFromFormat($format, $a['date_time_rdv']);
$d2 = DateTime::createFromFormat($format, $b['date_time_rdv']);
return $d2 <=> $d1;
}
usort($array, 'date_compare');
It will output :
Array
(
[0] => Array
(
[id] => 2
[date_time_rdv] => 2020-02-13 10:05:25
)
[1] => Array
(
[id] => 3
[date_time_rdv] => 2019-02-15 22:18:45
)
[2] => Array
(
[id] => 1
[date_time_rdv] => 2018-02-22 11:29:35
)
)
If you use uasort()
instead, it will output this (it will maintain index association)
Array
(
[1] => Array
(
[id] => 2
[date_time_rdv] => 2020-02-13 10:05:25
)
[2] => Array
(
[id] => 3
[date_time_rdv] => 2019-02-15 22:18:45
)
[0] => Array
(
[id] => 1
[date_time_rdv] => 2018-02-22 11:29:35
)
)
If you try return $d1 <=> $d2;
, it will reverse the order.
In date_compare()
, we use DateTime::createFromFormat
which parses a time string according to a specified format. You could use the format you need, like in the op question dd/mm/YYYY
More info on DateTime::createFromFormat :
Upvotes: 1
Reputation: 112
so do it like this:
//your array
$arr = array();
array_push($arr, array("11/05/2013", "Executive Planning Day"));
array_push($arr, array("13/06/2013", "Middle Leaders Planning Day"));
array_push($arr, array("12/07/2013", "New Staff Induction Day"));
array_push($arr, array("13/04/2013", "Staff Conference Day No. 1"));
array_push($arr, array("14/04/2013", "Staff Conference Day No. 2"));
array_push($arr, array("15/02/2013", "Staff Conference Day No. 3"));
array_push($arr, array("16/03/2013", "Australia Day"));
var_dump($arr);
function sortDateDesc($a, $b){
$strA = implode("-", array_reverse( explode("/", $a[0]) ) );
$strB = implode("-", array_reverse( explode("/", $b[0]) ) );
return strtotime($strB) - strtotime($strA);
}
usort($arr, "sortDateDesc");
var_dump($arr);
If your date format is constant day/month/year then you need to pass it in a string format recognized by the parser and year-month-day is an ISO standard if I remember it well, that one works fine
Upvotes: 1
Reputation: 354
I jumped here for associative array sorting and found this amazing function on http://php.net/manual/en/function.sort.php. This function is very dynamic that sort in ascending and descending order with specified key.
Simple function to sort an array by a specific key. Maintains index association.
<?php
function array_sort($array, $on, $order=SORT_ASC)
{
$new_array = array();
$sortable_array = array();
if (count($array) > 0) {
foreach ($array as $k => $v) {
if (is_array($v)) {
foreach ($v as $k2 => $v2) {
if ($k2 == $on) {
$sortable_array[$k] = $v2;
}
}
} else {
$sortable_array[$k] = $v;
}
}
switch ($order) {
case SORT_ASC:
asort($sortable_array);
break;
case SORT_DESC:
arsort($sortable_array);
break;
}
foreach ($sortable_array as $k => $v) {
$new_array[$k] = $array[$k];
}
}
return $new_array;
}
$people = array(
12345 => array(
'id' => 12345,
'first_name' => 'Joe',
'surname' => 'Bloggs',
'age' => 23,
'sex' => 'm'
),
12346 => array(
'id' => 12346,
'first_name' => 'Adam',
'surname' => 'Smith',
'age' => 18,
'sex' => 'm'
),
12347 => array(
'id' => 12347,
'first_name' => 'Amy',
'surname' => 'Jones',
'age' => 21,
'sex' => 'f'
)
);
print_r(array_sort($people, 'age', SORT_DESC)); // Sort by oldest first
print_r(array_sort($people, 'surname', SORT_ASC)); // Sort by surname
Upvotes: 2
Reputation: 3583
I spent a night working on how to do this for my own similar issue. To sort an associative array by date of a key in that array.
Both usort and uasort require a sort function that you must write and pass as the second parameter. The sort function is used by usort and uasort to compare each item in the array and store the result as $yourArray
function sortFunction( $a, $b ) {
return strtotime($a[1]) - strtotime($b[1]);
}
uasort($yourArray, "sortFunction");
Upvotes: 3
Reputation: 1
$sortdate = array(
'17/08/2015',
'02/01/2017',
'05/02/2014'
);
function sortFunction($a, $b)
{
$datea = strtotime(str_replace('/', '-', $a));
$dateb = strtotime(str_replace('/', '-', $b));
if ($datea == $dateb)
{
return 0;
}
return ($datea < $dateb) ? -1 : 1;
}
usort($sortdate, "sortFunction");
echo "<pre>";
var_dump($sortdate);
Upvotes: 0
Reputation: 311
The solution of @Gautam3164 is almost perfect. You need to change the format of the dates. I'd say:
function sortFunction( $a, $b ) {
return strtotime(str_replace('/', '-',$a[1])) - strtotime(str_replace('/', '-',$b[1]));
}
usort($data, "sortFunction"); //Here You can use asort($data,"sortFunction")
11/10/1987 -> 10 Nov 1987 11-10-1987 -> 11 Oct 1987
Upvotes: 0
Reputation: 10148
Not entirely happy with all of the answers here so I thought I'd mention that if you wish to sort an associative array preserving the keys then you should use uasort
rather than usort
. You can also parse the date from any format you like with the DateTime
library which also includes some predefined constants for some of the standard formats.
uasort($array, function($a, $b){
$format = 'd/m/Y';
$ascending = false;
$zone = new DateTimeZone('UTC');
$d1 = DateTime::createFromFormat($format, $a[1], $zone)->getTimestamp();
$d2 = DateTime::createFromFormat($format, $b[1], $zone)->getTimestamp();
return $ascending ? ($d1 - $d2) : ($d2 - $d1);
});
Upvotes: 2
Reputation: 28763
Try like this
function sortFunction( $a, $b ) {
return strtotime($a[1]) - strtotime($b[1]);
}
usort($data, "sortFunction"); //Here You can use asort($data,"sortFunction")
or you may try by detail like(its just suggestion)
function sortFunction($a,$b)
if ($a[1] == $b[1]) return 0;
return strtotime($a[1]) - strtotime($b[1]);
}
usort($data,"sortFunction");
As the strtotime is not obey d/m/Y format try like this
$orderByDate = $my2 = array();
foreach($data as $key=>$row)
{
$my2 = explode('/',$row[1]);
$my_date2 = $my2[1].'/'.$my2[0].'/'.$my2[2];
$orderByDate[$key] = strtotime($my_date2);
}
array_multisort($orderByDate, SORT_DESC, $data);
Upvotes: 22
Reputation: 3765
Use usort()
function:
function cmp($a, $b) {
if ($a[1] == $b[1]) return 0;
return (strtotime($a[1]) < strtotime($b[1])) ? 1 : -1;
}
usort($data, "cmp");
Upvotes: 2
Reputation: 4268
Use usort(Sort an array by values using a user-defined comparison function).
usort($array, function($a1, $a2) {
$value1 = strtotime($a1['date']);
$value2 = strtotime($a2['date']);
return $value1 - $value2;
});
Upvotes: 2
Reputation: 19039
I'd build an array for ordering.
$ordered = array();
foreach ($planning as $event) {
$ordered[$event['date']] = $event;
}
ksort($ordered);
Upvotes: 1