Home > front end >  How to can i have a multidimentional array by periods
How to can i have a multidimentional array by periods

Time:12-30

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].

  •  Tags:  
  • php
  • Related