Splitting dates - php

$one = array('start' => '2012-10-12', 'stop' => '2012-11-04', 'over' => false);
$two = array('start' => '2012-10-29', 'stop' => '2012-11-14', 'over' => true);
$three = array('start' => '2012-11-12', 'stop' => '2012-12-07', 'over' => false);
$array = array($one, $two, $three);
this show me:
Array
(
[0] => Array
(
[start] => 2012-10-12
[stop] => 2012-11-04
[over] =>
)
[1] => Array
(
[start] => 2012-10-29
[stop] => 2012-11-14
[over] => 1
)
[2] => Array
(
[start] => 2012-11-12
[stop] => 2012-12-07
[over] =>
)
)
I would like make function for splitting these dates.
If in array is over = true then this date should split other dates.
For this example this should return:
Array
(
[0] => Array //this is changed
(
[start] => 2012-10-12
[stop] => 2012-10-28
[over] =>
)
[1] => Array //this is ok
(
[start] => 2012-10-29
[stop] => 2012-11-14
[over] => 1
)
[2] => Array //this is changed
(
[start] => 2012-11-15
[stop] => 2012-12-07
[over] =>
)
)
And second example:
$one = array('start' => '2012-10-12', 'stop' => '2012-12-04', 'over' => false);
$two = array('start' => '2012-10-29', 'stop' => '2012-11-14', 'over' => true);
$second = array($one, $two);
this return me:
Array
(
[0] => Array
(
[start] => 2012-10-12
[stop] => 2012-12-04
[over] =>
)
[1] => Array
(
[start] => 2012-10-29
[stop] => 2012-11-14
[over] => 1
)
)
and i would like receive:
Array
(
[0] => Array //this is changed - old [0] date
(
[start] => 2012-10-12
[stop] => 2012-10-28
[over] =>
)
[1] => Array //this is ok
(
[start] => 2012-10-29
[stop] => 2012-11-14
[over] => 1
)
[2] => Array //this is new - from old [0] date - next part
(
[start] => 2012-11-15
[stop] => 2012-12-04
[over] =>
)
)
http://codepad.org/tqtEYstB
http://codepad.org/6fYkYVQ8
How can I do it with PHP?

Try this.
foreach($arr as $key=>$val)
{
if(isset($arr[$key+1]) && $arr[$key+1]['over'] == true)
$arr[$key]['stop'] = date('Y-m-d', strtotime($arr[$key+1]['start'] .' -1 day'));
if(isset($arr[$key-1]) && $arr[$key-1]['over'] == true)
$arr[$key]['start'] = date('Y-m-d', strtotime($arr[$key-1]['stop'] .' +1 day'));
}
you can find the code here.
Update:
$arr1 = $arr;
foreach($arr as $key=>$val)
{
if(isset($arr[$key+1]) && $arr[$key+1]['over'] == true)
{
$arr[$key]['stop'] = date('Y-m-d', strtotime($arr[$key+1]['start'] .' -1 day'));
$arr[$key]['over'] = true;
}
if(isset($arr[$key-1]) && $arr[$key-1]['over'] == true)
{
$arr[$key]['start'] = date('Y-m-d', strtotime($arr[$key-1]['stop'] .' +1 day'));
$arr[$key]['over'] = true;
}
}
foreach($arr1 as $key=>$val)
{
$arr[$key]['over'] = $arr1[$key]['over'];
}
your updated code here.

Related

Filter dates in a nested php array

I have this nested array, it's in a variable called $dates_list
Array
(
[0] => Array
(
[0] => Array
(
[event_date] => 2020-11-19 00:00:00
[event_start_time] => 13:07:00
[event_end_time] => 17:07:00
)
[1] => Array
(
[event_date] => 2020-06-17 00:00:00
[event_start_time] => 10:07:00
[event_end_time] => 17:07:00
)
[2] => Array
(
[event_date] => 2020-03-05 00:00:00
[event_start_time] => 15:46:00
[event_end_time] => 20:46:00
)
)
[1] => Array
(
[0] => Array
(
[event_date] => 2020-07-07 00:00:00
[event_start_time] => 20:10:00
[event_end_time] => 20:10:00
)
[1] => Array
(
[event_date] => 2020-03-13 00:00:00
[event_start_time] => 20:10:00
[event_end_time] => 20:10:00
)
)
)
and I've got a variable called $now
$now = date("Y-m-d h:i:s");
// 2020-03-13 02:28:32
How do I filter out all the event_date keys that are older than $now?
If event_date is the same as $now I'd like that to be left in the array
Desired result
I'm hoping to be able to get it to look like this, notice [event_date] => 2020-03-05 00:00:00 has been removed
Array
(
[0] => Array
(
[0] => Array
(
[event_date] => 2020-11-19 00:00:00
[event_start_time] => 13:07:00
[event_end_time] => 17:07:00
)
[1] => Array
(
[event_date] => 2020-06-17 00:00:00
[event_start_time] => 10:07:00
[event_end_time] => 17:07:00
)
)
[1] => Array
(
[0] => Array
(
[event_date] => 2020-07-07 00:00:00
[event_start_time] => 20:10:00
[event_end_time] => 20:10:00
)
[1] => Array
(
[event_date] => 2020-03-13 00:00:00
[event_start_time] => 20:10:00
[event_end_time] => 20:10:00
)
)
)
You have to loop all items in Array and then compare dates:
foreach($dates_list as $key=>$item) {
foreach($item as $k=>$value) {
if (date("Y-m-d h:i:s", strtotime($value["event_date"])) < $now) {
unset($dates_list[$key][$k]);
}
}
}
You could use the array_filter_recursive() suggested in this user comment and just recurisvely filter through the arrays:
function array_filter_recursive($input, $callback = null)
{
foreach ($input as &$value) {
if (is_array($value)) {
$value = array_filter_recursive($value, $callback);
}
}
return array_filter($input, $callback);
}
$array = [
[
['event_date' => '2020-11-19 00:00:00'],
['event_date' => '2020-06-17 00:00:00'],
['event_date' => '2020-03-05 00:00:00'],
],
[
['event_date' => '2020-07-07 00:00:00'],
['event_date' => '2020-03-13 00:00:00'],
]
];
$currentTime = '2020-03-13 02:28:32'; // date and time from question
$filtered = array_filter_recursive($array, function($value) use ($currentTime) {
// do not remove the first-level arrays
if (!isset($value['event_date'])) {
return true;
}
return $value['event_date'] > $currentTime;
});
var_export($filtered);
output:
array (
0 =>
array (
0 =>
array (
'event_date' => '2020-11-19 00:00:00',
),
1 =>
array (
'event_date' => '2020-06-17 00:00:00',
),
),
1 =>
array (
0 =>
array (
'event_date' => '2020-07-07 00:00:00',
),
),
)

Create Array From Current Array using PHP

This is the result of array after i build it using array_push function from mssql result.
Array
(
[0] => Array
(
[STICKER] => FALCON
[MONTH] => 1
[JUM] => 65826210.00
)
[1] => Array
(
[STICKER] => FALCON
[MONTH] => 2
[JUM] => 68070573.00
)
[2] => Array
(
[STICKER] => FALCON
[MONTH] => 3
[JUM] => 99053067.60
)
[3] =>
[4] => Array
(
[STICKER] => HRD
[MONTH] => 2
[JUM] => 1521400.00
)
[5] => Array
(
[STICKER] => HRD
[MONTH] => 3
[JUM] => 2093200.00
)
)
I need to convert array above into this structure:
Array
(
[0] => Array
(
[0] =>
[1] => 1
[2] => 2
[3] => 3
)
[1] => Array
(
[0] => FALCON
[1] => 65826210.00
[2] => 68070573.00
[3] => 99053067.60
)
[2] => Array
(
[0] => HRD
[1] => 0
[2] => 1521400.00
[3] => 2093200.00
)
)
Note:
Array[0] values would be 1,2,3 (this is actualy month, i just input up to 3 in order to get the code not too long. but it will be up to 12 (Jan - Dec)).
If from original array, there is none value (example from array[3]), then it will be convert to new array[2]->[1] with value 0.
Any help would be very appreciated.
Thanks all!.
Try this,
If any month is not mentioned from stickers the jum considered as 0,
$array = array(
array('STICKER' => 'FALCON', 'MONTH' => 1, 'JUM' => 65826210.00),
array('STICKER' => 'FALCON', 'MONTH' => 2, 'JUM' => 68070573.00),
array('STICKER' => 'FALCON', 'MONTH' => 3, 'JUM' => 99053067.60),
array(),
array('STICKER' => 'HRD', 'MONTH' => 2, 'JUM' => 1521400.00),
array('STICKER' => 'HRD', 'MONTH' => 3, 'JUM' => 2093200.00),
);
$result[0][] = '';
foreach ($array as $key => $res) {
if (!empty($res)) {
$result[0][$res['MONTH']] = $res['MONTH'];
$result1[$res['STICKER']][$res['MONTH']] = $res['JUM'];
}
}
foreach ($result1 as $key => $res) {
$fin = array();
foreach ($res as $key1 => $re) {
foreach ($result[0] as $key2 => $month) {
if ($month != '') {
if (array_key_exists($month, $res)) {
if (!array_key_exists($month, $fin) && $month == $key1) {
$fin[$month] = $re;
}
} else {
$fin[$month] = 0;
}
}
}
}
$result[] = array_merge(array($key), $fin);
}
echo'<pre>';
print_r($result);
echo'<pre>';
Result:
Array
(
[0] => Array
(
[0] =>
[1] => 1
[2] => 2
[3] => 3
)
[1] => Array
(
[0] => FALCON
[1] => 65826210
[2] => 68070573
[3] => 99053067.6
)
[2] => Array
(
[0] => HRD
[1] => 0
[2] => 1521400
[3] => 2093200
)
)
I hope this is used to achieve your output(you mentioned in above question)!!
try something like this
not the issue with the empty array i could not understand how the program would know that it is STICKER HRD so it will be filled with zero.But you could later check if every month "isset" and if it is not act as it is zero
$arr1=array(
array('STICKER'=>'FALCON','MONTH'=>1,'JUM'=>65826210.00),
array('STICKER'=>'FALCON','MONTH'=>2,'JUM'=>68070573.00),
array('STICKER'=>'FALCON','MONTH'=>3,'JUM'=>99053067.60),
array(),
array('STICKER'=>'HRD','MONTH'=>2,'JUM'=>1521400.00),
array('STICKER'=>'HRD','MONTH'=>3,'JUM'=>2093200.00),
);
$arr2=array();
$arr3=array();
$arr2[0][0]="";
foreach($arr1 as $key => $val){
if(!empty($val)){
$arr2[0][$val['MONTH']]=$val['MONTH'];
//group each STICKER
$arr3[$val['STICKER']][]=$val['JUM'];
}
}
//transfer the grouped data to arr2
foreach($arr3 as $key => $val){
$tmp_arr=array($key);
$arr2[]=array_merge($tmp_arr,$val);
}
print_r($arr2);

Get averages of values from multidimensional array where date key's match?

I have the following multidimensional array,
Array
(
[0] => Array
(
[place] => 1
[date] => 2013-01-01
)
[1] => Array
(
[place] => 2
[date] => 2013-01-02
)
[2] => Array
(
[place] => 3
[date] => 2013-01-03
)
[3] => Array
(
[place] => 10
[date] => 2013-01-01
)
[4] => Array
(
[place] => 8
[date] => 2013-01-02
)
[5] => Array
(
[place] => 5
[date] => 2013-01-03
)
)
How can I get the average place each array where the dates match, so the out put array would look like? The most i've been able to do is loop over the arrays extracting the dates which is pretty easy but finding matches and getting the averages is beyond me. Thanks in advance.
Array
(
[0] => Array
(
[place] => 5.5
[date] => 2013-01-01
)
[1] => Array
(
[place] => 5
[date] => 2013-01-02
)
[2] => Array
(
[place] => 6.5
[date] => 2013-01-03
)
)
$input = array(
array('place' => 1, 'date' => '2013-01-01'),
array('place' => 2, 'date' => '2013-01-02'),
array('place' => 3, 'date' => '2013-01-01'),
);
foreach($input as $pair) $tmp[$pair['date']][] = $pair['place'];
foreach($tmp as $key => $value){
$result[] = array('place' => array_sum($value) / count($value), 'date' => $key);
}
//var_dump($result);
Result:
array (size=2)
0 =>
array (size=2)
'place' => int 2
'date' => string '2013-01-01' (length=10)
1 =>
array (size=2)
'place' => int 2
'date' => string '2013-01-02' (length=10)
You could parse your input array into an array where the keys are the dates and the values are arrays of places for that date:
$tmp = array();
foreach( $input as $entry ) {
$date = $entry["date"];
if( !array_key_exists( $date, $tmp ) ) {
$tmp[$date] = array();
}
$tmp[$date][] = $entry["place"];
}
And now just go over that temporary array, calculate the averages and produce the output format you want:
$averages = array();
foreach( $tmp as $date => $places ) {
$sum = array_sum($places);
$averages[] = array(
"date" => $date,
"place" => $sum / count($places)
);
}
print_r($averages);

Eliminate timestamps within a range from array

This is my array of timestamps. I would like to eliminate values within 30 seconds of each other, only keeping the value if there is not another value within 30 sec. Any help would be greatly appreciated!
Array
(
[99999] => Array
(
[0] => 1356399000
[1] => 1356398971
[2] => 1356399005
[3] => 1356413406
)
[99997] => Array
(
[0] => 1356399002
[1] => 1356399007
[2] => 1356398871
[3] => 1356398876
)
[99996] => Array
(
[0] => 1356399003
[1] => 1356399004
[2] => 1356399008
)
[99995] => Array
(
[0] => 1356399009
)
)
My expected output:
Array
(
[99999] => Array
(
[0] => 1356399000
[1] => 1356398971
[2] => 1356413406
)
[99997] => Array
(
[0] => 1356399002
[1] => 1356398871
)
[99996] => Array
(
[0] => 1356399003
)
[99995] => Array
(
[0] => 1356399009
)
)
Any solutions/advice would be greatly appreciated! Thanks!
Your output is wrong .. because 1356398971 + 30 = 1356399001 which is grater than 1356399000 if i understand you clearly this i what it should look like
$data = array(
99999 => array(
0 => 1356399000,
1 => 1356398971,
2 => 1356399005,
3 => 1356413406,
),
99997 => array(
0 => 1356399002,
1 => 1356399007,
2 => 1356398871,
3 => 1356398876,
),
99996 => array(
0 => 1356399003,
1 => 1356399004,
2 => 1356399008,
),
99995 => array(
0 => 1356399009,
),
);
echo "<pre>";
$data = array_map(function ($values) {
rsort($values);
$ci = new CachingIterator(new ArrayIterator($values));
$values = array();
foreach ( $ci as $ts ) {
if ($ci->hasNext()) {
abs($ci->current() - $ci->getInnerIterator()->current()) > 30 and $values[] = $ts;
} else {
$values[] = $ts;
}
}
sort($values);
return $values;
}, $data);
print_r($data);
Output
Array
(
[99999] => Array
(
[0] => 1356398971
[1] => 1356413406
)
[99997] => Array
(
[0] => 1356398871
[1] => 1356399002
)
[99996] => Array
(
[0] => 1356399003
)
[99995] => Array
(
[0] => 1356399009
)
)

How to merge two arrays of dates ignoring duplicate dates and then sort by date

For example, I have $dates1 and $dates2 shown below, and want to create $dates3, which keeps all dates in $dates1, and adds any unique dates in $dates2, ignoring any duplicates. The arrays contain other values but I'm just showing the dates because that's what I want to merge/sort on.
$dates1=
Array
(
[0] => Array
(
[day] => 2012-01-01
[foo] => "bar"
)
[1] => Array
(
[day] => 2012-01-02
[foo] => "bar"
)
[2] => Array
(
[day] => 2012-01-03
[foo] => "bar"
)
)
$dates2=
Array
(
[0] => Array
(
[day] => 2011-12-31
)
[1] => Array
(
[day] => 2012-01-01
)
[2] => Array
(
[day] => 2012-01-02
)
[3] => Array
(
[day] => 2012-01-03
)
[4] => Array
(
[day] => 2012-01-04
)
)
So I would like to merge $dates2 into $dates1, ignoring any duplicates, to make $dates3:
Array
(
[0] => Array
(
[day] => 2011-12-31
)
[1] => Array
(
[day] => 2012-01-01
[foo] => "bar"
)
[2] => Array
(
[day] => 2012-01-02
[foo] => "bar"
)
[3] => Array
(
[day] => 2012-01-03
[foo] => "bar"
)
[4] => Array
(
[day] => 2012-01-04
)
)
I'm not sure I understand you correctly, do you mean something like this?
$old_array = array_merge($dates1, $dates2);
$new_array = array();
foreach ($old_array as $item){
if (!array_key_exists($item['day'], $new_array)){
$new_array[$item['day']] = $item;
}
}
return $new_array;
Something like this should work
$a1 = array(array('day' => '2012-01-01', 'foo' => 'bar1'),
array('day' => '2012-01-02', 'foo' => 'bar2'),
array('day' => '2012-01-03', 'foo' => 'bar3'));
$a2 = array(array('day' => '2011-12-31'),
array('day' => '2012-01-01'),
array('day' => '2012-01-02'),
array('day' => '2012-01-03'),
array('day' => '2012-01-04'));
$orderedArray = array();
foreach (array_merge($a1, $a2) as $v)
{
if (count($v) == 1 && isset($orderedArray[$v['day']]))
continue;
$orderedArray[$v['day']] = $v;
}
ksort($orderedArray);
print_r($orderedArray);
Edit: I refactored the code.

Categories