Filter multidimensional array of dates to exclude weekends (saturdays and sundays)

1.8k views Asked by At

I'm looping through an array of days in the current month to generate another array of days that are on or after the current day and this is working well. I now need to exclude/omit any dates if they are a Saturday or a Sunday.

I'm trying to work out if it's possible to include a check for Saturday/Sunday dates, something like:

date('N', strtotime($day)) >= 6);

with my existing code that generates an array:

// Get days for current month
    $day = date("Y-m-d");
    $i = strtotime($day);
    
    array("year" => array("month" => array(days)));
    $allDays = array(
        date('Y', $i) => array(
            date('n') => range(date('d', $i), intval(date('t'))),
        ),
    );

Not sure how to combine the test for a weekend date with this or whether I need to use a for loop etc here?

3

There are 3 answers

3
Amal Murali On BEST ANSWER

Assuming you're trying to get all the days excluding weekends for the current month: you could use array_filter() with a callback to get the weekend days and then use array_diff() to create a new array containing only week days:

$year = date('Y');
$month = date('n');

$weekend_days = array_filter($allDays[$year][$month], function($d) {
    return (date('N', strtotime(date("Y-m-$d"))) >= 6);
});

$allDays[$year][$month] = array_diff($allDays[$year][$month], $weekend_days);

print_r($allDays);
2
Seth On

You can do a check on the date before adding each value to the array:

if (!in_array(date('w', $i), array('0', '6')))
{
    // add $i to array
}
0
mickmackusa On

Instead of filtering the populated multidimensional array, perhaps you'd like to populate the desired array from the start.

Declare a datetime object for the first day of the current month. Cache the month value for future reference. Wind back the date by one day to reach the last day of the previous month. Use the phrase "next weekday" to advance the object to only the next desired day. Push the qualifying dates into your result array in the desired format.

Code: (Demo)

$result = [];
$dt = new DateTime('first day of this month');
$month = $dt->format('n');
$dt->modify('-1 day');
while ($dt->modify('next weekday') && $dt->format('n') == $month) {
    $result[$dt->format('Y')][$dt->format('n')][] = $dt->format('d');
}
var_export($result);

As an extension of this implementation, a multi-year array can be populated in a similar fashion.

The result is an array with year values as the first level keys, month values as second level keys, and weekdays as the third level values.

$result = [];
foreach ([2023, 2024] as $year) {
    $dt = new DateTime("$year-01-01 -1 day");
    while ($dt->modify('next weekday') && $dt->format('Y') == $year) {
        $result[$year][$dt->format('n')][] = $dt->format('d');
    }
}
var_export($result);