Reputation: 37
I have an array with dates. I have to determine which dates belongs to which periods. For that purpose I have two other arrays - one with start dates and one with end dates for these periods.
I have tried foreach loops for the dates and the DatePeriod class but I couldn't get it to work.
foreach ($dates as $value) {
foreach ($startdates as $key => $value1) {
foreach ($enddates as $key => $value2) {
if ($value > $value1 && $value < $value2) {
result[$value] = $key;
}
}
}
}
dates (extract) / $dates
$dates = Array ( [0] => 2011-04-11
[1] => 2011-06-28
[2] => 2011-09-26
[3] => 2012-01-02
[4] => 2012-05-12 )
start dates with assigned keys (extract) / $startdates
Array ( [10] => 2011-01-01
[20] => 2011-07-01
[30] => 2012-01-01
[40] => 2012-07-01 )
end dates with assigned keys (extract) / $enddates
Array ( [10] => 2011-06-30
[20] => 2011-12-31
[30] => 2012-06-30
[40] => 2012-12-31 )
I would like the result to be a new array, where the dates in the $dates array becomes keys and the periods in the start- and end dates arrays becomes values like this:
Array ( [2011-04-11] => 10
[2011-06-28] => 10
[2011-09-26] => 20
[2012-01-02] => 30
[2012-05-12] => 30 )
Upvotes: 0
Views: 346
Reputation: 47894
Because you are comparing Y-m-d formatted dates, you don't need date/time functions -- in other words, just treat the dates as strings.
Simultaneously iterate the start and end elements. When you find the correct range, store the data and continue with the next date to assess.
Code: (Demo)
$dates = ['2011-04-11', '2011-06-28', '2011-09-26', '2012-01-02', '2012-05-12'];
$startdates = [
10 => '2011-01-01',
20 => '2011-07-01',
30 => '2012-01-01',
40 => '2012-07-01'
];
$enddates = [
10 => '2011-06-30',
20 => '2011-12-31',
30 => '2012-06-30',
40 => '2012-12-31'
];
foreach ($dates as $date) {
foreach ($startdates as $key => $startdate) {
if ($date >= $startdate && $date <= $enddates[$key]) {
$result[$date] = $key;
continue 2;
}
}
$result[$date] = 'out of bounds';
}
var_export($result);
Output:
array (
'2011-04-11' => 10,
'2011-06-28' => 10,
'2011-09-26' => 20,
'2012-01-02' => 30,
'2012-05-12' => 30,
)
Upvotes: 1
Reputation: 18557
You can loop around your main dates variable for the period of start and end date arrays,
// combining keys and values
$temp = array_combine($startdates, $enddates);
$result = [];
// & for making changes on assigned address of variable regardless of array_walk function scope
array_walk($dates, function ($item, $key) use (&$result, $temp, $startdates) {
foreach ($temp as $k => $v) {
// comparing with start and end date range
if (strtotime($item) >= strtotime($k) && strtotime($item) <= strtotime($v)) {
// searching by value and getting key
$result[$item] = array_search($k, $startdates);
// if comes to this loop break as its never gonna come here
break;
}
}
});
array_combine — Creates an array by using one array for keys and another for its values
array_walk — Apply a user supplied function to every member of an array
array_search — Searches the array for a given value and returns the first corresponding key if successful
Output
Array
(
[2011-04-11] => 10
[2011-06-28] => 10
[2011-09-26] => 20
[2012-01-02] => 30
[2012-05-12] => 30
)
Demo.
Upvotes: 1