Skip to main content

Business hours calculation using PHP



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.


                                                     Demo

 <?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 
}
?>

Comments

Post a Comment

Thank you :)

Popular posts from this blog

Laravel form validations

 Laravel Validations: List of types "first_name" => 'required|alpha:ascii|min:3|max:100',// alpha:ascii (only accepts a-z) "middle_name" => 'string', "last_name" => 'required|string', "email" => 'required|email|unique:users,email', "password" => 'required|string|confirmed', "sex" => 'required|string', "phone_no" => 'required|string', "account_type" => 'required|string', "dob" => 'required|date_format:d-m-Y', // date with format "nationality" => 'required|string', "company" => 'required|string', "company_sector" => 'required|string', "company_address" => 'required|string' "bank_account_no" => 'required|min_digits:3|max_digits:5', "role" => 'required|in:admin,editor,viewer', ...

React Js Commands

React JS Commands and Useful purposes  To Install react app: npx create-react-app app-name To Install react app: npx create-react-app . To check npm version: npm --version Inside that directory, you can run several commands:   npm start     Starts the development server.   npm run build     Bundles the app into static files for production.   npm test     Starts the test runner.   npm run eject     Removes this tool and copies build dependencies, configuration files     and scripts into the app directory. If you do this, you can’t go back! node -v (To check node version) The latest recommended command to create a new React app is: npx create-react-app@latest my-app Replace my-app with your desired project name. This approach uses the latest version of Create React App and works if Node.js (version 14+) and npm (version 5.2+) are installed Modern Alternatives If you prefer a faster, lighter setup, many developers n...

AngularJS - Directives

First, we have to learn AngularJs directives, Directives are simple special attributes in HTML. It has own set of built-in directives which offers functionality to your applications. To check all directive list https://docs.angularjs.org/api/ng/directive  For example, I take ng-app , ng-model ,  ng-init and ng-bind .  First will talk about the ng-app directive, the ng-app directive is initializing the AngularJS application. To take the values of all HTML inputs ( input, radio, select and textarea ) we use the ng-model.     ng-bind is print the expression. we can also be written inside double braces: {{ expression }} . AngularJS - Directives Example 1  Note: All these directives are work in inside the ng-app closed tag. you can assign ng-app directive to any tag. like <HTML>, <DIV>, <SPAN> but make sure initialize the main parent tag.     Now, We can check data initializes before page load. For this, ...