I want to calculate the number of working days.
By using carbon I can calculate days and reduce weekends.
$num_days = $to_date->diffInWeekdays($from_date) + 1;
And I have an array of holidays, and I want to reduce the number of days if there is a holiday in between the days.
Is there any way to do this.
Thank you
You could use diffInDaysFiltered
to achieve what you're after.
Assuming your holidays are an array of Carbon
instances you could do something like:
$start = Carbon::now()->setDate(2014, 1, 1);
$end = Carbon::now()->setDate(2015, 1, 1);
$holidays = [
Carbon::create(2014, 2, 2),
Carbon::create(2014, 4, 17),
Carbon::create(2014, 5, 19),
Carbon::create(2014, 7, 3),
];
$days = $start->diffInDaysFiltered(function (Carbon $date) use ($holidays) {
return $date->isWeekday() && !in_array($date, $holidays);
}, $end);
If it's just an array of strings then you could do something like:
!in_array($date->format('[the-format-of-your-dates]'), $holidays)
Hope this helps!
Here is a small utility function to calculate working days:
function getWorkingDaysCount($from, $to) {
$workingDays = [1, 2, 3, 4, 5]; // Working days (week days)
$holidayDays = ['*-12-25', '*-01-01']; // Holidays array, add desired dates to this array
$from = new DateTime($from);
$to = new DateTime($to);
$to->modify('+1 day');
$interval = new DateInterval('P1D');
$periods = new DatePeriod($from, $interval, $to);
$days = 0;
foreach ($periods as $period) {
if (!in_array($period->format('N'), $workingDays)) continue;
if (in_array($period->format('Y-m-d'), $holidayDays)) continue;
if (in_array($period->format('*-m-d'), $holidayDays)) continue;
$days++;
}
return $days;
}
You can pass the starting and end date to get the number of days.
You can get this by following code
<?php
function workdays($start,$end,$holidays){
$end = strtotime($end);
$start = strtotime($start);
$days = ($end - $start) / 86400 + 1;
$no_full_weeks = floor($days / 7);
$no_remaining_days = fmod($days, 7);
$the_first_day_of_week = date("N", $start);
$the_last_day_of_week = date("N", $end);
if ($the_first_day_of_week <= $the_last_day_of_week) {
if ($the_first_day_of_week <= 6 && 6 <= $the_last_day_of_week) $no_remaining_days--;
if ($the_first_day_of_week <= 7 && 7 <= $the_last_day_of_week) $no_remaining_days--;
}
else {
if ($the_first_day_of_week == 7) {
$no_remaining_days--;
if ($the_last_day_of_week == 6) {
$no_remaining_days--;
}
}
else {
$no_remaining_days -= 2;
}
}
$workingDays = $no_full_weeks * 5;
if ($no_remaining_days > 0 )
{
$workingDays += $no_remaining_days;
}
foreach($holidays as $holiday){
$time_stamp=strtotime($holiday);
if ($start <= $time_stamp && $time_stamp <= $end && date("N",$time_stamp) != 6 && date("N",$time_stamp) != 7)
$workingDays--;
}
return $workingDays;
}
echo workdays("2016-01-04","2016-01-30",array("2016-01-25","2016-01-26","2016-01-27"))
?>
function getWorkingDays($days1,$start_dt,$end_dt,$holidays) {
$date1 = $start_dt;
$date2 = $end_dt;
$array = array();
$query = $holidays;// pass array of holidays.
foreach($query as $row)
{
$array[] = $row['h_date'];
}
$workingDays = [1, 2, 3, 4, 5];// 1 = Mon,...
$holidayDays = $array; # variable and fixed holidays
$from = new DateTime($date1);
$to = new DateTime($date2);
$to->modify('+1 day');
$interval = new DateInterval('P1D');
$periods = new DatePeriod($from, $interval, $to);
$nameOfDay = date('N', strtotime($date1));
if($nameOfDay==7)
{
$nameOfDay=0;
}
$days = $nameOfDay;
$fullDate=explode('-',$date1);
$y=$fullDate['0'];
$m=$fullDate['1'];
$d=$fullDate['2'];
foreach ($periods as $period) {
if (!in_array($period->format('N'), $workingDays)) {
$d++;
continue;
}
if (in_array($period->format('Y-m-d'), $holidayDays)) {
if($d==32 && $m==12)
{
$d=1;
$m=1;
$y++;
}
$d++;
continue;
}
if (in_array($period->format('*-m-d'), $holidayDays)) {
$d++;
continue;
}
switch ($m) {
case '2':
if( (0 == $y % 4) and (0 != $y % 100) or (0 == $y % 400) )
{
if($d>=30)
{
$d=1;
$m++;
break;
}
}
else
{
if($d>=29)
{
$d=1;
$m++;
break;
}
}
case '4':
case '6':
case '9':
case '11':
if($d>=31)
{
$d=1;
$m++;
}
break;
case '1':
case '3':
case '5':
case '7':
case '8':
case '10':
if($d>=32)
{
$d=1;
$m++;
}
break;
case '12':
if($d>=32)
{
$d=1;
$m=1;
$y++;
}
break;
}
$dn = date('D', strtotime($d.'-'.$m.'-'.$y));
if($d==1 && $dn=='Sun')
{
$d++;
}
if($d==1 && $dn=='Sat')
{
$d=$d+2;
}
$dayName = date('D', strtotime($d.'-'.$m.'-'.$y));
$planbookid = $this->planbook->get_planbook_id();
$d++;
$days++;
}
echo json_encode($result);
}