Most of ticketing alert projects needed SLA calculation to exclude holidays and weekends or Off business hours.
First of all, let us take a look at types of SLA we need to calculate.
For instance, few companies will work 24/7 shifts and 8x5, 8x7 etc.
So we need to consider business hours. In this example, I'm considering business hours which starts at 09:00 AM and ends at 06:00 PM. Also, using this code we can calculate 24/7 too.
Let's consider business hours started at 9:00 AM to 18:00 PM without weekends.
Now, take the actual work start period and end period.
<?php
$incident_work_started = '2018-09-12 09:28:07';
$incident_work_ended = '2018-09-19 17:45:00';
$totalHours = round(get_working_hours($incident_work_started,$incident_work_ended),2)."\n";
echo "Total hours: ".$totalHours;
function get_working_hours($work_started,$work_ended)
{
// business hours start at 9:00 AM to 18:00. Consider that in an array [hrs,mins]
$buss_start = array(9,00); // hours, minutes
$buss_end = array(18,00); // hours, minutes
// Convert $work_started and $work_ended date into date object.
// Reason to converting, To get difference of time "2018-09-12 09:28:00" to "2018-09-12 09:00:00". here will get 28 mins
$work_started_date_obj = date_create($work_started); // Date will converted to date object
$work_ended_date_obj = date_create($work_ended); // Date will converted to date object
//Now, set $work_started to $buss_start to get difference
$ini_buss_start_time = date_time_set(date_create($work_started),$buss_start[0],$buss_start[1]); // "2018-09-12 09:28:00" to "2018-09-12 09:00:00"
$ini_buss_end_time = date_time_set(date_create($work_ended),$buss_end[0],$buss_end[1]); // "2018-09-19 17:45:00" to "2018-09-19 18:00:00"
// To get actual working days and skip weekends(Sat & Sun) and holidays.
$actual_worked_days = get_workdays($work_started_date_obj,$work_ended_date_obj);
$actual_worked_days_count = count($actual_worked_days);
// convert business hours to seconds for calculating time difference
$workday_seconds = (($buss_end[0] * 60 + $buss_end[1]) - ($buss_start[0] * 60 + $buss_start[1])) * 60;
//echo $current->format('U')."";
//echo date('Y/m/d H:i:s', $current->format('U'))."";
//get time difference
$ini_seconds = 0;
$end_seconds = 0;
if(in_array($work_started_date_obj->format('Y-m-d'),$actual_worked_days))
{
$ini_seconds = $work_started_date_obj->format('U') - $ini_buss_start_time->format('U');
/* we will get 1687 seconds, beacuase we given date "2018-09-12 09:28:07" our business
hours start at 9:00:00 (h:m:s) so need take seconds from 9:00:00. Finally we get seconds
of 9:00:00 to 09:28:07 is 1687. */
}
if(in_array($work_ended_date_obj->format('Y-m-d'),$actual_worked_days))
{
$end_seconds = $ini_buss_end_time->format('U') - $work_ended_date_obj->format('U');
}
$seconds_dif = $ini_seconds > 0 ? $ini_seconds : 0;
if($end_seconds > 0)
{
$seconds_dif += $end_seconds;
}
/* Final Calculation, Hence we got total number of working days $actual_worked_days_count and $workday_seconds.
business start at 9:00:00 AM but here work started at 9:28:07
so we should subtraction the 28:07 (m:s) total 1687 seconds and business ends at 18:00:00
but here work closed at 17:45:00 then subtraction will get (15:00) total 900 seconds. so total 2587 seconds. */
$working_seconds = ($actual_worked_days_count * $workday_seconds) - $seconds_dif;
/* here we get total number of working day seconds ($actual_worked_days_count * $workday_seconds)
and subtraction none used seconds $seconds_dif will get actual working seconds. */
echo 'Working Hours:'.($working_seconds / 3600)."\n";
return $working_seconds / 3600; //return hrs
}
function get_workdays($work_started,$work_ended)
{
//To skip saturday and sunday weekends
$weekdays = [0,6]; // sunday:0 monday:1...saturday:6;
$holidays = []; //eg: ['2018-12-25']; for public holidays
$current = clone $work_started; // Clone is used to load date objects.
// Get date format from $work_started and end date
$start_date = $work_started->format('Y-m-d');
$end_date = $work_ended->format('Y-m-d');
// To store valid working days after avoid weekends and holidays
$days_arr = [];
//So we have $start_date, $end_date, $weekdays and $holidays. We need to take work dates between all these days.
while($start_date <= $end_date){
if(!in_array($current->format('w'),$weekdays) && !in_array($start_date,$holidays)){
$days_arr[] = $start_date;
}
$current->add(new DateInterval('P1D')); //adds one day
$start_date = $current->format('Y-m-d');
}
return $days_arr; // return the valid worked days
}
?>
Nice one...
ReplyDeleteIts very usefull
ReplyDeletecan you please share the (timthumb.php) source code also
DeleteGreat Blog!!! Was an interesting blog with a clear concept. And will surely help many to update them.
ReplyDeleteReactJS Training in Chennai
ReactJS Training
gst classes in chennai
ux design course in chennai
ReactJS course
Web Designing Course in Chennai
Ethical Hacking Course in Chennai
Tally Course in Chennai