Reputation: 5846
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
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
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
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