I'm creating a planner and I would like to group by time frame, for example : the month number 2 (February) is booked. that's why is not in $free_time_frame
$free_time_frame = [];
$start = new DateTime("2022-01-01");
$end = new DateTime("2022-12-31");
$interval = new DateInterval("P1M"); // 1 month interval
$period = new DatePeriod($start, $interval, $end);
$seasons = [8,2];
foreach ($period as $date) {
if (in_array($date->format("n"), $seasons)) {
// Skip the rest of the loop if the current month is in the $seasons array
continue;
}
// Set the start date to the first day of the month
$start_date = new DateTime($date->format("Y-m-01"));
// Set the end date to the last day of the month
$end_date = new DateTime($date->format("Y-m-t"));
// Calculate the number of days between the start and end dates
$diff = $start_date->diff($end_date);
$days = $diff->days 1; // Add 1 to include the end date
$free_time_frame[] = [
"from" => $start_date->format("Y-m-d"),
"to" => $end_date->format("Y-m-d"),
"slot" => $days,
];
$start->modify(" 1 month");
}
This is the result :
[{
"from": "2022-01-01",
"to": "2022-01-31",
"frame": 31,
"season": 1
}, {
"from": "2022-03-01",
"to": "2022-03-31",
"frame": 31,
"season": 3
}, {
"from": "2022-04-01",
"to": "2022-04-30",
"frame": 30,
"season": 4
}, {
"from": "2022-05-01",
"to": "2022-05-31",
"frame": 31,
"season": 5
}, {
"from": "2022-06-01",
"to": "2022-06-30",
"frame": 30,
"season": 6
}, {
"from": "2022-07-01",
"to": "2022-07-31",
"frame": 31,
"season": 7
}, {
"from": "2022-09-01",
"to": "2022-09-30",
"frame": 30,
"season": 9
}, {
"from": "2022-10-01",
"to": "2022-10-31",
"frame": 31,
"season": 10
}, {
"from": "2022-11-01",
"to": "2022-11-30",
"frame": 30,
"season": 11
}, {
"from": "2022-12-01",
"to": "2022-12-31",
"frame": 31,
"season": 12
}]
What I want to accomplish :
Like you see I have a flat array contain all the months but February. I would like to put the months before $season
in an array and the ones after $season
in another array, always inside $free_time_frame
The expected result :
[
[
{
"from":"2022-01-01",
"to":"2022-01-31",
"frame":31,
"season":1
}
],
[
{
"from":"2022-03-01",
"to":"2022-03-31",
"frame":31,
"season":3
},
{
"from":"2022-04-01",
"to":"2022-04-30",
"frame":30,
"season":4
},
{
"from":"2022-05-01",
"to":"2022-05-31",
"frame":31,
"season":5
},
{
"from":"2022-06-01",
"to":"2022-06-30",
"frame":30,
"season":6
},
{
"from":"2022-07-01",
"to":"2022-07-31",
"frame":31,
"season":7
}
],
[
{
"from":"2022-09-01",
"to":"2022-09-30",
"frame":30,
"season":9
},
{
"from":"2022-10-01",
"to":"2022-10-31",
"frame":31,
"season":10
},
{
"from":"2022-11-01",
"to":"2022-11-30",
"frame":30,
"season":11
},
{
"from":"2022-12-01",
"to":"2022-12-31",
"frame":31,
"season":12
}
]
]
CodePudding user response:
PHP does not support "multi-dimensional arrays". What you want are nested arrays.
Just add empty arrays when a season break occurs and use that. Initialize with a first nested array.
<?php declare(strict_types = 1);
$free_time_frame = [[]]; // nested array here
$start = new DateTime("2022-01-01");
$end = new DateTime("2022-12-31");
$interval = new DateInterval("P1M"); // 1 month interval
$period = new DatePeriod($start, $interval, $end);
$seasons = [8,2];
foreach ($period as $date) {
if (in_array($date->format("n"), $seasons)) {
// Skip the rest of the loop if the current month is in the $seasons array
$free_time_frame[] = []; // append nested array
continue;
}
// Set the start date to the first day of the month
$start_date = new DateTime($date->format("Y-m-01"));
// Set the end date to the last day of the month
$end_date = new DateTime($date->format("Y-m-t"));
// Calculate the number of days between the start and end dates
$diff = $start_date->diff($end_date);
$days = $diff->days 1; // Add 1 to include the end date
// use the latest nested array
$free_time_frame[array_key_last($free_time_frame)][] = [
"from" => $start_date->format("Y-m-d"),
"to" => $end_date->format("Y-m-d"),
"slot" => $days,
];
$start->modify(" 1 month");
}
echo json_encode($free_time_frame, JSON_PRETTY_PRINT);
You might want to extend your algorithm to check, whether the latest nested array is empty before adding a new one, e.g. when $seasons
is like [2,3,10]
.