skip to Main Content

I have the following array called $exhibitions:

Array
(
    [0] => Array
        (
            [exhibition_title] => Picasso
            [venue_name] => Gallery 1
            [room_name] => Room 4
            [start_date] => 2023-11-15
            [end_date] => 2023-12-10
            [room_id] => 261
            [exhibition_id] => 3540
            [venue_order] => 2
        )

    [1] => Array
        (
            [exhibition_title] => Monet
            [venue_name] => Gallery 4
            [room_name] => Room 2
            [start_date] => 2023-10-01
            [end_date] => 2023-11-13
            [room_id] => 274
            [exhibition_id] => 8417
            [venue_order] => 1
        )
)

What I need to do is use the start_date and end_date to create a range of dates each exhibition is open, and then for each of those dates essentially duplicate the rest of the information in the existing sub-array with the individual date appended to the end of the sub-array. My desired output would be:

Array
(
    [0] => Array
        (
            [exhibition_title] => Picasso
            [venue_name] => Gallery 1
            [room_name] => Room 4
            [start_date] => 2023-11-15
            [end_date] => 2023-12-10
            [room_id] => 261
            [exhibition_id] => 3540
            [venue_order] => 2
            November 21, 2023 => 2023-11-15
        )
    [1] => Array
        (
            [exhibition_title] => Picasso
            [venue_name] => Gallery 1
            [room_name] => Room 4
            [start_date] => 2023-11-15
            [end_date] => 2023-12-10
            [room_id] => 261
            [exhibition_id] => 3540
            [venue_order] => 2
            November 21, 2023 => 2023-11-16
        )
    [2] => Array
        (
            [exhibition_title] => Picasso
            [venue_name] => Gallery 1
            [room_name] => Room 4
            [start_date] => 2023-11-15
            [end_date] => 2023-12-10
            [room_id] => 261
            [exhibition_id] => 3540
            [venue_order] => 2
            November 21, 2023 => 2023-11-17
        )
    [... etc. for the rest of the dates in the Picasso date range]

    [25] => Array
        (
            [exhibition_title] => Monet
            [venue_name] => Gallery 4
            [room_name] => Room 2
            [start_date] => 2023-10-01
            [end_date] => 2023-11-13
            [room_id] => 274
            [exhibition_id] => 8417
            [venue_order] => 1
            November 21, 2023 => 2023-10-01
        )

    [26] => Array
        (
            [exhibition_title] => Monet
            [venue_name] => Gallery 4
            [room_name] => Room 2
            [start_date] => 2023-10-01
            [end_date] => 2023-11-13
            [room_id] => 274
            [exhibition_id] => 8417
            [venue_order] => 1
            November 21, 2023 => 2023-10-02
        )

    [27] => Array
        (
            [exhibition_title] => Monet
            [venue_name] => Gallery 4
            [room_name] => Room 2
            [start_date] => 2023-10-01
            [end_date] => 2023-11-13
            [room_id] => 274
            [exhibition_id] => 8417
            [venue_order] => 1
            November 21, 2023 => 2023-10-03
        )
    [... etc. for the rest of the dates in the Monet date range]
)

I saw this similar post and modified it so that instead of echoing the $given_date, it added it to the array in a new column called "date".

foreach ($exhibitions as $key => $value) {

    $startDate = strtotime($value['start_date']);
    $endDate = strtotime($value['end_date']);

    // Loop between timestamps, 24 hours at a time
    for ($i = $startDate; $i <= $endDate; $i = $i + 86400 ) {
            $given_date = date('Y-m-d', $i );     
            $exhibitions[$key]['date'] = $given_date;
    }    

};

The problem was that instead of adding one date per date in the date range, it added the last date in the range only. When I echoed the $given_date just to make sure it was iterating each date, it lists every date in the range, so I’m assuming there’s something wrong with how I added the new column but I can’t figure out what.

2

Answers


  1. There is a small mistake in your code. You are overwriting the ‘date’ key in each iteration of the loop, so only the last date is stored in the original array. I have rewrite the code for you, please have a look, hope it will solve you issue.

    <?php
    
    $exhibitions = array(
        array(
            'exhibition_title' => 'Picasso',
            'venue_name' => 'Gallery 1',
            'room_name' => 'Room 4',
            'start_date' => '2023-11-15',
            'end_date' => '2023-12-10',
            'room_id' => 261,
            'exhibition_id' => 3540,
            'venue_order' => 2,
        ),
        array(
            'exhibition_title' => 'Monet',
            'venue_name' => 'Gallery 4',
            'room_name' => 'Room 2',
            'start_date' => '2023-10-01',
            'end_date' => '2023-11-13',
            'room_id' => 274,
            'exhibition_id' => 8417,
            'venue_order' => 1,
        )
    );
    
    $result = array();
    
    foreach ($exhibitions as $key => $value) {
        $startDate = strtotime($value['start_date']);
        $endDate = strtotime($value['end_date']);
    
        // Loop between timestamps, 24 hours at a time
        for ($i = $startDate; $i <= $endDate; $i = $i + 86400) {
            $given_date = date('Y-m-d', $i);
    
            // Create a new array for each date and append it to the result array
            $result[] = array(
                'exhibition_title' => $value['exhibition_title'],
                'venue_name' => $value['venue_name'],
                'room_name' => $value['room_name'],
                'start_date' => $value['start_date'],
                'end_date' => $value['end_date'],
                'room_id' => $value['room_id'],
                'exhibition_id' => $value['exhibition_id'],
                'venue_order' => $value['venue_order'],
                'date' => $given_date,
            );
        }
    }
    
    // $result now contains the desired output
    print_r($result);
    
    ?>
    

    You can check the output on this link https://onecompiler.com/php/3ztkkmvw9

    Login or Signup to reply.
    • Iterate your input array’s rows and access the start and end dates.
    • Create an iterable payload of dates using PHP’s native DateTime methods.
    • Loop over those dates, append the individual date to the row data, then pass the extended row into the result array.

    To have an "inclusive" range of dates, add 1 day to the end date (otherwise every range will be one day short).

    By appending the generated date to the row data with the union operator (+), you avoid needing to write out every element in the row while pushing.

    Code: (Demo)

    $result = [];
    foreach ($exhibitions as $row) {
        $dateRange = new DatePeriod(
            new DateTime($row['start_date']),
            new DateInterval('P1D'),  // 1 day per step
            new DateTime("{$row['end_date']} +1 day")  // +1 day to include end date
        );
        foreach ($dateRange as $d) {
            $result[] = $row + ['date' => $d->format("Y-m-d")];
        }
    }
    var_export($result);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search