I have an array of timestamps that look like this:
2012-11-19 19:45
I need to sort them by date. I could do a bubble sort or something if i could get the unix timestamp of a date, but i don't know what function gives me that. I looked at strtotime but it won't let me pass a date format. I'm also not sure a bubble sort is the best way to go.
Any suggestions?
Array example:
Also, sorry, i should have mentioned it was in 'show_date'.
Array
(
[15] => Array
(
[show_date] => 2012-11-19 10:40
)
[16] => Array
(
[show_date] => 2012-11-20 10:40
)
[17] => Array
(
[show_date] => 2012-11-21 10:40
)
[18] => Array
(
[show_date] => 2012-11-22 10:40
)
)
No need to overcomplicate this. Just use the built-in sort function:
sort($timestamp_array);
You don't need to convert to UNIX timestamps because the strings are in the standard "ISO sortable date" format. That means that if you sort the strings, the dates will be in the correct order.
Here is a php -a session that shows how it works:
php > $ts = array('1986-01-31 12:11', '2012-01-01 13:12', '1980-10-10 12:00');
php > sort($ts);
php > echo var_export($ts);
array (
0 => '1980-10-10 12:00',
1 => '1986-01-31 12:11',
2 => '2012-01-01 13:12',
)
You can just sort it with PHP standard sort. See Sorting Arrays
asort($timestamps);
For your example, you can define a comparison function
function cmp_show_date($a, $b)
{
if ($a['show_date'] == $b['show_date']) {
return 0;
}
return ($a['show_date'] < $b['show_date']) ? -1 : 1;
}
and use that in usort
usort($timestamps, 'cmp_show_date');
You could use a combination of usort() and strtotime, but I'd rather use the DateTime class and its getTimestamp method because it can handle time zones and several formats.
You do not need date format to pass that particular date. When you pass strtotime('2012-11-19 19:45'); it will return UNIX time stamp.
EDIT:
$arr = array();
foreach ($dates as $k => $v) {
$arr[$k] = strtotime($v['date']);//or $k if your date is the index
}
array_multisort($arr, SORT_ASC, $dates);
Related
My Final array for showing notifications is like:
Array
(
[0] => Array
(
[notification] => 1 new topic posted in : Current Affairs classroom
[on_create] => 12th Aug - 2016 5:20AM
[notif_date_sort] => 2016-08-12 05:20:23
)
[1] => Array
(
[notification] => 8 new topic posted in : GK classroom
[on_create] => 4th Aug - 2016 10:51AM
[notif_date_sort] => 2016-08-04 10:51:56
)
)
I tried methods like multisort, ksort but didnt find proper result. How to sort this elements inside array based on "notif_date_sort" ?
You can use usort() with your own function to sort the results by date.
Like this,
usort($array, 'custom_date_sort');
function custom_date_sort($a,$b) {
$date1 = DateTime::createFromFormat('Y-m-d H:i:s', $a["notif_date_sort"]);
$date2 = DateTime::createFromFormat('Y-m-d H:i:s', $b["notif_date_sort"]);
return $date1>$date2;
}
Where DateTime::createFromFormat creates the DateTime object from the string.
You need to use usort() function.
Try this:
function compare_dates($date1, $date2){
$date1 = strtotime($date1['notif_date_sort']);
$date2 = strtotime($date2['notif_date_sort']);
if ($date1 == $date2) {
return 0;
}
return ($date2 < $date2) ? -1 : 1;
}
usort($array, "compare_dates");
I have an array of timestamps that I'm importing from different XML files. This is how they look like:
<field name="timestamp">2015-04-16T07:14:16Z</field>
So I have a bunch of them stored in an array named $timestamps like this:
2015-04-16T07:14:16Z
2015-04-24T14:34:50Z
2015-04-25T08:07:24Z
2015-04-30T07:48:12Z
2015-05-02T08:37:01Z
2015-05-09T10:41:45Z
2015-05-01T07:27:21Z
2015-05-07T09:41:36Z
2015-05-12T04:06:11Z
2015-05-12T05:52:52Z
2015-05-12T11:28:16Z
I am only interested in the date part, not the time. I have tried splitting the string using the split() function.
$dates = array();
for ($i=0; $i<count($timestamps); $i++){
$dates = split ("T", $timestamps[$i]);
echo $dates[$i] . "<br>";
}
From what I understand it is storing the first part (before the T) then the part after the T. How can it store only the first part of each string?
When I try this:
echo $dates[1];
it outputs the first date fine. I'm not quite sure about the rest.
Any suggestions on a better way to accomplish this?
Thanks!
You should use strtotime and date, as opposed to string splitting and/or regex. This will help if your date format ever changes.
$dates = array();
foreach ($timestamps as $timestamp) {
$d = strtotime($timestamp);
$dates[] = date('Y-m-d', $d);
}
foreach ($dates as $date) {
echo $date . '<br/>';
}
I think splitting is not better the best is get date using date function easily. Very easy code:-
<?php
$dates = array('2015-04-16T07:14:16Z','2015-04-24T14:34:50Z','2015-04-25T08:07:24Z','2015-04-30T07:48:12Z','2015-05-02T08:37:01Z'); // i hope your dates array is like this
foreach($dates as $date){
echo date('Y-m-d',strtotime($date)).'<br/>';
}
?>
Output:- http://prntscr.com/78b0x4
Note:-I didn't take your whole array. Because it's easy to see and understand what i am doing there in my code. thanks.
You can simply use preg_replace() to remove all the "time" bits in the array:
$array = Array('2015-04-16T07:14:16Z', '2015-04-24T14:34:50Z', '2015-04-25T08:07:24Z');
// Remove "T" and anything after it
$output = preg_replace('/T.*/', '', $array);
print_r($output);
Outputs:
Array
(
[0] => 2015-04-16
[1] => 2015-04-24
[2] => 2015-04-25
)
There's no reason to drag date and strotime into this, that's just extra overhead. You have an expected, regular format already.
And I would also give a warning about using date functions: you may run into trouble with the values changing after you put them through date and strtotime depending on your server's date/time(zone) settings! Since your strings do not specify the timezone offset, you won't even be able to properly convert.. you'll just have to roll with whatever your server is at or pick one yourself.
The safer way to ensure the actual value doesn't change is to just parse it as a string. Splitting at the "T" is fine. You're just having trouble with how to handle the variables. Here is an example:
// example data
$timestamps =<<<EOT
015-04-16T07:14:16Z
2015-04-24T14:34:50Z
2015-04-25T08:07:24Z
2015-04-30T07:48:12Z
2015-05-02T08:37:01Z
2015-05-09T10:41:45Z
2015-05-01T07:27:21Z
2015-05-07T09:41:36Z
2015-05-12T04:06:11Z
2015-05-12T05:52:52Z
2015-05-12T11:28:16Z
EOT;
$timestamps=explode("\n",$timestamps);
$dates = array();
for ($i=0; $i<count($timestamps); $i++){
$d = explode("T", $timestamps[$i]);
$dates[] = $d[0];
}
print_r($dates);
output:
Array
(
[0] => 015-04-16
[1] => 2015-04-24
[2] => 2015-04-25
[3] => 2015-04-30
[4] => 2015-05-02
[5] => 2015-05-09
[6] => 2015-05-01
[7] => 2015-05-07
[8] => 2015-05-12
[9] => 2015-05-12
[10] => 2015-05-12
)
I'm having some troubles sorting events for my website in wordpress.
I'm using custom fields to create events with a title, a description and a date.
I put every events date in an array:
$datesEvenements = array();
array_push($datesEvenements,get_field('date'));
I then get the timestamp for each date:
foreach($datesEvenements as $value){
$timestamp = strtotime($value);
array_push($tsEvenements,$timestamp);
}
I then proceed to sort my timestamp by replacing the past event by 0 or an association of the event timestamp with the difference between that timestamp and the present one.
$arrEventDelta = array();
for($i=0;$i<count($tsEvenements);$i++){
$tsi = $tsEvenements[$i];
if($ts>$tsi){
array_push($arrEventDelta,0);
}
elseif($ts<=$tsi){
array_push($arrEventDelta,array('TimestampEvenements'=>$tsi,'DeltaEvenements'=>$deltaTs));
}
After that, I would like to order the array '$arrEventDelta' by the 'DeltaEvenements' value.
Unfortunately, I'm a bit confused with all those arrays. I've tried the array_multisort function like so:
$DeltaEvents = array();
foreach($arrEventDelta as $key => $row){
$DeltaEvents[$key] = $row['DeltaEvents'];
}
array_multisort($DeltaEvents, SORT_ASC, $arrEventDelta);
But it doesn't work. Any tips on how I could fix this?
This is what is outputed from this,
Array ( [0] => 0 [1] => Array ( [TimestampEvenements] => 1394582400 [DeltaEvenements] => **31923** ) [2] => Array ( [TimestampEvenements] => 1394668800 [DeltaEvenements] => **118323** ) [3] => 0 [4] => 0 )
I need to order the highlighted numbers in increasing order.
I have a merged array from the JSON output of a Facebook and Twitter stream and I want to sort those two into one but they offer two different timestamps:
Facebook: [created_time] => 1299839651
Twitter: [created_at] => Mon Mar 07 16:33:49 +0000 2011
Currently the output contains the full JSON content from both platforms beginning with Array ( [data] => Array ( [0] => Array ( [id] => (Facebook) and ending with [id_str] => 12345678964508161 ) ) (Twitter).
In the middle part it looks like this: &limit=25&until=0 ) [0] => Array ( [text] => (Facebook -> Twitter).
I am not sure how to handle this. Thanks for help.
You can use strtotime() to convert the Twitter timestamp into one that looks more like the Facebook timestamp.
Then you simply order them based on the numerical timestamp
This should work, assuming I understood your problem correctly.
<?php
// assume $array is your array of associative arrays with created_time
// being facebook timestamps, created_at being twitter
// takes as arguments two associative arrays with
// created_time keys to compare
function sort_by_created_time($arr1, $arr2)
{
if ($arr1['created_time'] == $arr2['created_time'])
{
return 0;
}
elseif ($arr1['created_time'] > $arr2['created_time'])
{
return 1;
}
else
{
return -1;
}
}
// go through each array, generate timestamps if needed
foreach ($array as &$row)
{
if (!isset($row['created_time']))
{
// convert date formats to timestamps if we need to
$row['created_time'] = strtotime($row['created_at']);
}
}
unset($row);
usort($array, "sort_by_created_time");
I have an array in this format:
Array
(
[0] => Array
(
[28th February, 2009] => 'bla'
)
[1] => Array
(
[19th March, 2009] => 'bla'
)
[2] => Array
(
[5th April, 2009] => 'bla'
)
[3] => Array
(
[19th April, 2009] => 'bla'
)
[4] => Array
(
[2nd May, 2009] => 'bla'
)
)
I want to sort them out in the ascending order of the dates (based on the month, day, and year). What's the best way to do that?
Originally the emails are being fetched in the MySQL date format, so its possible for me to get the array in this state:
Array
[
['2008-02-28']='some text',
['2008-03-06']='some text'
]
Perhaps when its in this format, I can loop through them, remove all the '-' (hyphen) marks so they are left as integars, sort them using array_sort() and loop through them yet again to sort them? Would prefer if there was another way as I'd be doing 3 loops with this per user.
Thanks.
Edit: I could also do this:
$array[$index]=array('human'=>'28 Feb, 2009',
'db'=>'20080228',
'description'=>'Some text here');
But using this, would there be any way to sort the array based on the 'db' element alone?
Edit 2: Updated initial var_dump
Use the ISO (yyyy-mm-dd) format rather than the "english" format, and then just use the ksort function to get them in the right order.
There's no need to remove the hyphens, ksort will do an alphanumeric comparison on the string keys, and the yyyy-mm-dd format works perfectly well as the lexical order is the same as the actual date order.
EDIT I see you've now corrected your question to show that you've actually got an array of arrays, and that the sort key is in the sub-arrays. In this case, you should use uksort as recommended elsewhere, but I would recommend that you go with your own edit and sort based on the DB formatted date, rather than by parsing the human readable format:
function cmp($a, $b)
{
global $array;
return strcmp($array[$a]['db'], $array[$b]['db']);
}
uksort($array, 'cmp');
Actually, use this:
usort($array, "cmp");
function cmp($a, $b){
return strcmp($b['db'], $a['db']);
}
:)
function cmp($a, $b) {
global $array;
return strcmp($array[$a]['db'], $array[$b]['db']);
}
uksort($array, 'cmp');
I think there is better to use usort() function instead of uksort(), because sometimes you can`t use global variables at all and anyway using global variables is not a good practice either.
You could also use an anonymous function.
// Sort in chronological order.
usort($array, function($a, $b) {
return strcmp($a['db'], $b['db']);
});