skip to Main Content

I have a date range 1st Nov to 30th Nov.

I block the date 3rd Nov to 6th Nov And 15th Nov to 20th Nov.

Now I want to show the available dates like 1th to 2nd Nov, 7th to 14th Nov And 21th to 30th Nov.

This is my array of date range

Array
(
    [0] => Array
        (
            July 11, 2023 => 2023-11-01
            [IsBlocked] => false
        )

    [1] => Array
        (
            July 11, 2023 => 2023-11-02
            [IsBlocked] => false
        )

    [2] => Array
        (
            July 11, 2023 => 2023-11-03
            [IsBlocked] => true
        )

    [3] => Array
        (
            July 11, 2023 => 2023-11-04
            [IsBlocked] => true
        )

    [4] => Array
        (
            July 11, 2023 => 2023-11-05
            [IsBlocked] => true
        )

    [5] => Array
        (
            July 11, 2023 => 2023-11-06
            [IsBlocked] => true
        )

    [6] => Array
        (
            July 11, 2023 => 2023-11-07
            [IsBlocked] => false
        )

    [7] => Array
        (
            July 11, 2023 => 2023-11-08
            [IsBlocked] => false
        )

    [8] => Array
        (
            July 11, 2023 => 2023-11-09
            [IsBlocked] => false
        )

    [9] => Array
        (
            July 11, 2023 => 2023-11-10
            [IsBlocked] => false
        )

    [10] => Array
        (
            July 11, 2023 => 2023-11-11
            [IsBlocked] => false
        )

    [11] => Array
        (
            July 11, 2023 => 2023-11-12
            [IsBlocked] => false
        )

    [12] => Array
        (
            July 11, 2023 => 2023-11-13
            [IsBlocked] => false
        )

    [13] => Array
        (
            July 11, 2023 => 2023-11-14
            [IsBlocked] => false
        )

    [14] => Array
        (
            July 11, 2023 => 2023-11-15
            [IsBlocked] => true
        )

    [15] => Array
        (
            July 11, 2023 => 2023-11-16
            [IsBlocked] => true
        )

    [16] => Array
        (
            July 11, 2023 => 2023-11-17
            [IsBlocked] => true
        )

    [17] => Array
        (
            July 11, 2023 => 2023-11-18
            [IsBlocked] => true
        )

    [18] => Array
        (
            July 11, 2023 => 2023-11-19
            [IsBlocked] => true
        )

    [19] => Array
        (
            July 11, 2023 => 2023-11-20
            [IsBlocked] => true
        )

    [20] => Array
        (
            July 11, 2023 => 2023-11-21
            [IsBlocked] => false
        )

    [21] => Array
        (
            July 11, 2023 => 2023-11-22
            [IsBlocked] => false
        )

    [22] => Array
        (
            July 11, 2023 => 2023-11-23
            [IsBlocked] => false
        )

    [23] => Array
        (
            July 11, 2023 => 2023-11-24
            [IsBlocked] => false
        )

    [24] => Array
        (
            July 11, 2023 => 2023-11-25
            [IsBlocked] => false
        )

    [25] => Array
        (
            July 11, 2023 => 2023-11-26
            [IsBlocked] => false
        )

    [26] => Array
        (
            July 11, 2023 => 2023-11-27
            [IsBlocked] => false
        )

    [27] => Array
        (
            July 11, 2023 => 2023-11-28
            [IsBlocked] => false
        )

    [28] => Array
        (
            July 11, 2023 => 2023-11-29
            [IsBlocked] => false
        )

    [29] => Array
        (
            July 11, 2023 => 2023-11-30
            [IsBlocked] => false
        )

)

And I want to

Array
(
    [0] => Array
        (
            [start_date] => 2023-11-01
            [end_date] => 2023-11-02
        )
        
    [1] => Array
    (
        [start_date] => 2023-11-07
        [end_date] => 2023-11-14
    )

    [2] => Array
        (
            [start_date] => 2023-11-21
            [end_date] => 2023-11-30
        )
)

Please help me to solve this issue.

I’m try using this array but it’s not happening.

foreach($dates as $calDay) {
   if($calDay['IsBlocked'] == "true") {
       $closeDates[] = $calDay['date'];
   } else {
       $openDates[] = $calDay['date'];
   }
}

2

Answers


  1. $dates = [
        // ... your existing array of dates ...
    ];
    
    $availableRanges = [];
    $currentRange = null;
    
    foreach ($dates as $calDay) {
        if ($calDay['IsBlocked'] == "true") {
            // If the current range exists, add it to the availableRanges array
            if ($currentRange) {
                $availableRanges[] = $currentRange;
                $currentRange = null;
            }
        } else {
            // If the current range does not exist, create a new range
            if (!$currentRange) {
                $currentRange = [
                    'start_date' => $calDay['date'],
                    'end_date' => $calDay['date']
                ];
            }
            // Update the end_date of the current range
            $currentRange['end_date'] = $calDay['date'];
        }
    }
    
    // Add the last available range if it exists
    if ($currentRange) {
        $availableRanges[] = $currentRange;
    }
    

    In this code, the $availableRanges array will store the final result, and the $currentRange variable keeps track of the current range being processed. Whenever a blocked date is encountered, the current range is added to the $availableRanges array and reset to null. If an available date is found, a new range is created or the end_date of the current range is updated.

    At the end of the loop, the last available range (if it exists) is added to the $availableRanges array.

    The resulting $availableRanges array will contain the start and end dates of the available date ranges.

    Login or Signup to reply.
  2. Input array:

    $input = [
      [ 'date' => '2023-11-01', 'IsBlocked' => false ],
      [ 'date' => '2023-11-02', 'IsBlocked' => false ],
      [ 'date' => '2023-11-03', 'IsBlocked' => true ],
      [ 'date' => '2023-11-04', 'IsBlocked' => true ],
      [ 'date' => '2023-11-05', 'IsBlocked' => true ],
      [ 'date' => '2023-11-06', 'IsBlocked' => true ],
      [ 'date' => '2023-11-07', 'IsBlocked' => false ],
      [ 'date' => '2023-11-08', 'IsBlocked' => false ],
      [ 'date' => '2023-11-09', 'IsBlocked' => false ],
      [ 'date' => '2023-11-10', 'IsBlocked' => false ],
      [ 'date' => '2023-11-11', 'IsBlocked' => false ],
      [ 'date' => '2023-11-12', 'IsBlocked' => false ],
      [ 'date' => '2023-11-13', 'IsBlocked' => false ],
      [ 'date' => '2023-11-14', 'IsBlocked' => false ],
      [ 'date' => '2023-11-15', 'IsBlocked' => true ],
      [ 'date' => '2023-11-16', 'IsBlocked' => true ],
      [ 'date' => '2023-11-17', 'IsBlocked' => true ],
      [ 'date' => '2023-11-18', 'IsBlocked' => true ],
      [ 'date' => '2023-11-19', 'IsBlocked' => true ],
      [ 'date' => '2023-11-20', 'IsBlocked' => true ],
      [ 'date' => '2023-11-21', 'IsBlocked' => false ],
      [ 'date' => '2023-11-22', 'IsBlocked' => false ],
      [ 'date' => '2023-11-23', 'IsBlocked' => false ],
      [ 'date' => '2023-11-24', 'IsBlocked' => false ],
      [ 'date' => '2023-11-25', 'IsBlocked' => false ],
      [ 'date' => '2023-11-26', 'IsBlocked' => false ],
      [ 'date' => '2023-11-27', 'IsBlocked' => false ],
      [ 'date' => '2023-11-28', 'IsBlocked' => false ],
      [ 'date' => '2023-11-29', 'IsBlocked' => false ],
      [ 'date' => '2023-11-30', 'IsBlocked' => false ]
    ];
    

    First step is to collect the last date before and the first date after each change of ‘IsBlocked’:

    $dates = [];
    
    for ($i = 0, $iMax = count($input); $i < $iMax; $i++) {
      if ($i === 0 || $i === $iMax - 1) {
        $dates[] = $input[$i]['date'];
      } elseif ($input[$i]['IsBlocked'] !== $input[$i - 1]['IsBlocked']) {
        $dates[] = $input[$i - 1]['date'];
        $dates[] = $input[$i]['date'];
      }
    }
    

    This results in:

    Array
    (
        [0] => 2023-11-01
        [1] => 2023-11-02
        [2] => 2023-11-03
        [3] => 2023-11-06
        [4] => 2023-11-07
        [5] => 2023-11-14
        [6] => 2023-11-15
        [7] => 2023-11-20
        [8] => 2023-11-21
        [9] => 2023-11-30
    )
    

    Second step is to chunk this array into pairs of two and to filter the dates:

    $result = array_values(
      array_filter(
        array_chunk($dates, 2),
        fn($key) => $key % 2 === ( $input[0]['IsBlocked'] ? 1 : 0 ),
        ARRAY_FILTER_USE_KEY
      )
    );
    

    Output:

    Array
    (
        [0] => Array
            (
                [0] => 2023-11-01
                [1] => 2023-11-02
            )
    
        [1] => Array
            (
                [0] => 2023-11-07
                [1] => 2023-11-14
            )
    
        [2] => Array
            (
                [0] => 2023-11-21
                [1] => 2023-11-30
            )
    
    )
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search