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 = [];
$season = 2;
$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);
foreach ($period as $date) {
if ($date->format("n") == $season) {
// Skip the rest of the loop if the current month is August
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"),
"frame" => $days,
"season" => (int) $date->format('n'),
];
$start->modify(" 1 month");
}
return $free_time_frame;
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-08-01",
"to": "2022-08-31",
"frame": 31,
"season": 8
}, {
"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-08-01",
"to":"2022-08-31",
"frame":31,
"season":8
},
{
"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:
You can use your condition to fill another array :
free_time_frame = [];
elapsed_time_frame = []; //New array for elapsed time
elapsed=true;
$season = 2;
$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);
foreach ($period as $date) {
if ($date->format("n") == $season) {
elapsed=false;
// Skip the rest of the loop if the current month is August
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
if (!elapsed) {
$free_time_frame[] = [
"from" => $start_date->format("Y-m-d"),
"to" => $end_date->format("Y-m-d"),
"frame" => $days,
"season" => (int) $date->format('n'),
];
} else { //If elapsed
$elapsed_time_frame[] = [
"from" => $start_date->format("Y-m-d"),
"to" => $end_date->format("Y-m-d"),
"frame" => $days,
"season" => (int) $date->format('n'),
];
}
$start->modify(" 1 month");
}
return array_merge($elapsed_time_frame, $free_time_frame);
CodePudding user response:
here is sample.
$target = "2023-02";
$range = 12;
$initialMonth = new DateTime("2022-10");
$result = [];
for($index = 0; $index < $range; $index ){
$month = $initialMonth->modify(" 1 month")->format("Y-m");
if ($target === $month) {
continue;
}
$firstDate = date('Y-m-d', strtotime('first day of ' . $month));
$lastDate = date('Y-m-d', strtotime('last day of ' . $month));
$monthData = [
"from" => $firstDate,
"to" => $lastDate,
"frame" => (int) (new DateTime($lastDate))->format("d"),
"season" => (int) (new DateTime($lastDate))->format("m"),
];
$forTarget = (strtotime($monthData['to']) < strtotime($target)) ? 0 : 1;
$result[$forTarget][] = $monthData;
}
dd($result);
result is
array:2 [
0 => array:3 [
0 => array:4 [
"from" => "2022-11-01"
"to" => "2022-11-30"
"frame" => 30
"season" => 11
]
1 => array:4 [
"from" => "2022-12-01"
"to" => "2022-12-31"
"frame" => 31
"season" => 12
]
2 => array:4 [
"from" => "2023-01-01"
"to" => "2023-01-31"
"frame" => 31
"season" => 1
]
]
1 => array:8 [
0 => array:4 [
"from" => "2023-03-01"
"to" => "2023-03-31"
"frame" => 31
"season" => 3
]
1 => array:4 [
"from" => "2023-04-01"
"to" => "2023-04-30"
"frame" => 30
"season" => 4
]
2 => array:4 [
"from" => "2023-05-01"
"to" => "2023-05-31"
"frame" => 31
"season" => 5
]
3 => array:4 [
"from" => "2023-06-01"
"to" => "2023-06-30"
"frame" => 30
"season" => 6
]
4 => array:4 [
"from" => "2023-07-01"
"to" => "2023-07-31"
"frame" => 31
"season" => 7
]
5 => array:4 [
"from" => "2023-08-01"
"to" => "2023-08-31"
"frame" => 31
"season" => 8
]
6 => array:4 [
"from" => "2023-09-01"
"to" => "2023-09-30"
"frame" => 30
"season" => 9
]
7 => array:4 [
"from" => "2023-10-01"
"to" => "2023-10-31"
"frame" => 31
"season" => 10
]
]
]
I fix your code. you can change some target range or start month. try some.