danyo
danyo

Reputation: 5846

php determine if a range of dates fall on a weekend

I am building a a script to detect whether or not certain dates fall on a weekend every year.

The 25th and 26th are bank holidays, and if they fall on a weekend the next weekday is a substitute for that bank holiday and the remaining weekdays are working days.

Example: if the 25th is a saturday and 26th is a sunday, 27th and 28th will be bank holidays and then 29th, 30th, 31st are working days

if the 25th is a sunday, 26th and 27th, will then be bank holidays and 28th, 29th, 30th will be working days and the 31sy will be a saturday.

Here are my dates:

date('25-12-Y');
date('26-12-Y');
date('27-12-Y');
date('28-12-Y');
date('29-12-Y');
date('30-12-Y');
date('31-12-Y');

The code i have created is this: (please note the $getyear var is to test different years)

function isWeekend($date) {
    return (date('N', strtotime($date)) >= 6);
}
$getyear = 2013;

echo '25 ';
if (isWeekend(date('25-12-'.$getyear))){
   echo 'weekend'; 
} else {
    echo 'bh';
};
echo '<br>';
echo '26 ';
if (isWeekend(date('26-12-'.$getyear ))){
    echo 'weekend';
} else {
    echo 'bh';
};
echo '<br>';
echo '27 ';
if (isWeekend(date('27-12-'.$getyear ))){
    echo 'weekend'; 
} else { 
    echo 'leave';
};
echo '<br>';
echo '28 ';
if (isWeekend(date('28-12-'.$getyear ))){
    echo 'weekend'; 
} else {
    echo 'leave';
};
echo '<br>';
echo '29 ';
if (isWeekend(date('29-12-'.$getyear ))){
    echo 'weekend'; 
} else {
    echo 'leave';
};
echo '<br>';
echo '30 ';
if (isWeekend(date('30-12-'.$getyear ))){
    echo 'weekend'; 
} else {
    echo 'leave';
};
echo '<br>';
echo '31 ';
if (isWeekend(date('31-12-'.$getyear ))){
    echo 'weekend'; 
} else {
    echo 'leave';
};
echo '<br>';

I know this is probably not best practice, so i am looking for an alternative way to approach this.

Upvotes: 0

Views: 1395

Answers (3)

Robin van Baalen
Robin van Baalen

Reputation: 3651

This question and answer is ancient by now but I came across this particular issue today and came up with the following function:

if (!function_exists('hasWeekend')) {
    function hasWeekend (\DateTime $dateOne, \DateTime $dateTwo, $weekendDays = ["6", "7"]) {
        $diff = $dateTwo->diff($dateOne)->format('%a');
        $weekend = false;

        while ($diff > 0) {
            $date = $dateTwo->sub(new \DateInterval('P1D'));
            $day = $date->format('N');
            if (in_array($day, $weekendDays)) {
                $weekend = true;
                break;
            }

            $diff--;
        }

        return $weekend;
    }
}

Use it like this:

$hasWeekend = hasWeekend(new \DateTime('2019-11-25'), new \DateTime('2019-11-26'));
// $hasWeekend = false, Nov 25th is a Monday, Nov 26nd a Tuesday.

$hasWeekend = hasWeekend(new \DateTime('2019-11-27'), new \DateTime('2019-12-2'));
// $hasWeekend = true, December 2nd 2019 is a monday

If for whatever reason your weekend days are not Saturday and Sunday, you can change the $weekendDays array to represent the different days.

Upvotes: 0

MAQU
MAQU

Reputation: 562

$dates = array();
$christmas_days = array(25, 26);

$year = 2013;

for ($day = 25; $day <= 31; $day++)
{
    $dates[$day] = date($day . '-12-' . $year);
}



foreach ($dates as $day => $date)
{
    echo $day . ' ';
    if (isWeekend($date))
    {
        echo 'weekend';
        if (in_array($day, $christmas_days))
        {
            $bh_on_weekend++;
        }
    } 
    else
    {
        if ($bh_on_weekend > 0)
        {
            echo 'bh';
            $bh_on_weekend--;
        } 
        else
        {
            if (in_array($day, $christmas_days))
            {
                echo 'bh';
            } 
            else
            {
                echo 'leave';
            }
        }
    }
    echo '<br>';
}

function isWeekend($date)
{
    return (date('N', strtotime($date)) >= 6);
}

tried to do on the DRY way to repeat as less as possible. date creation is a bit more dynamical. hope it helps you somehow or give an idea how to make it different.

output for 2021

25 weekend
26 weekend
27 bh
28 bh
29 leave
30 leave
31 leave

Upvotes: 1

philipbrown
philipbrown

Reputation: 554

You should use Carbon to abstract all of that logic.

You can then do:

$dt = Carbon::create(2013, 12, 25);
$dt->isWeekday(); // bool

The Carbon documentation is really good, so I'm sure you will be able to find what you're looking for.

Upvotes: 0

Related Questions