skip to Main Content

I’m using Laravel 9 to create lessons scheduler,

I tried that way but Im little lost,

$free_time_frame = [[]];  // nested array here

$start = new DateTime("2023-01-01");
$end = new DateTime("2023-12-31");

$interval = new DateInterval("P1D"); // 1 month interval
$period = new DatePeriod($start, $interval, $end);
$seasons = ["2023-02-01", "2023-02-13"];
foreach ($period as $date) {
  if (in_array($date->format("Y-m-d"), $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
  

}

I’m booking $seasons I would like to have an array of the free days before "2023-02-01" and days after "2023-02-13" like that :

Expected Result

[
  [
   "2023-01-01",
   "2023-01-02",
   "2023-01-03",
   "..."
   "2023-01-31",
  ]
  [
   "2023-02-14",
   "2023-02-15",
   "2023-02-16",
   "2023-02-14",
   "and so on util the end of the year"
  ]
]

Thanks for the help in advance

3

Answers


  1. Okay, so I think I understand, that you want to get all dates between a range of dates, then exclude a specific range of date.

    You can do it like this:

    $originalDates = CarbonCarbonPeriod::between('2023-01-01', '2023-01-10')->toArray();
    $excludedDates = CarbonCarbonPeriod::between('2023-01-03', '2023-01-06')->toArray();
            
    $finalDates = [];
            
    foreach ($originalDates as $date) {
        if(!in_array($date, $excludedDates)){
            array_push($finalDates, $date->format('d-m-Y'));
        }
    }
        
    return $finalDates;
    

    This will return an array of the following results:

    01-01-2023
    02-01-2023
    07-01-2023
    08-01-2023
    09-01-2023
    10-01-2023
    

    Notice here that it skipped over from 2023-01-03 to 2023-01-06

    You can format this as you like by changing the line of $date->format('d-m-Y') to represent the results the way you want it, you can even remove the format to return a carbon array, which you can parse as you like somewhere else.

    And you can go one step further, and have multiple excludedDates, and check for them in_array

    Hopefully this helps, add a comment if you want further clarifications or modifications.

    Login or Signup to reply.
  2. To calculate free time from $seasons that doesn’t include in-between time period, it is just the everything before your first element of your seasons array and everything after last element of your seasons array.

    So, achieving this is just running 2 loops of DatePeriod in those ranges.

    <?php
    
    $seasons = ["2023-02-01", "2023-02-13", "2023-03-16"];
    
    $free_time_frame = [];
    
    $free_time_frame[] = getDaysInPeriod('2023-01-01', 'P1D', current($seasons));
    $free_time_frame[] = getDaysInPeriod(date("Y-m-d", strtotime(end($seasons). " +1 days")), 'P1D', '2024-01-01');
    
    
    function getDaysInPeriod($startDate, $dateInterval, $endDate){
      $span = [];
      foreach(new DatePeriod(new DateTime($startDate), new DateInterval($dateInterval),new DateTime($endDate)) as $p){
        $span[] = $p->format('Y-m-d');
      }
      return $span;
    }
    
    $free_time_frame = array_filter($free_time_frame);
    
    print_r($free_time_frame);
    

    Online Fiddle

    Login or Signup to reply.
  3. I think you can do the following:

    $startDate = '2023-01-01';
    $endDate = '2023-03-31';
    
    $seasons = ['2023-02-01', '2023-02-13'];
    
    $prepareSeasons = [
        [ $startDate, Carbon::parse($seasons[0])->subDay()->format('Y-m-d') ],
        [ Carbon::parse($seasons[0])->addDay()->format('Y-m-d'), $endDate ]
    ];
    
    // this is want we want to achieve
    // $prepareSeasons = [
    //     [$startDate, '2023-01-31'],
    //     ['2023-02-14', $endDate],
    // ];
    
    $freeTimeFrame = [];
    
    foreach ($prepareSeasons as $seasonDates)
    {
        $freeSeason = [];
    
        $seasonDates = CarbonPeriod::create($seasonDates[0], $seasonDates[1])->toArray();
    
        foreach ($seasonDates as $date)
        {
            array_push($freeSeason, $date->format('Y-m-d'));
        }
    
        array_push($freeTimeFrame, $freeSeason);
    }
    
    return $freeTimeFrame;
    

    The code above will achieve your expected result

    [
      [
       "2023-01-01",
       "2023-01-02",
       "2023-01-03",
       "...",
       "...",
       "2023-01-31",
      ],
      [
       "2023-02-14",
       "2023-02-15",
       "2023-02-16",
       "2023-02-14",
       "...",
       "...",
       "2023-12-31",
      ]
    ]
    

    I hope this can help you.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search