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

Data Types in Python

Data Types  In C# or Java, You need to declare a variable specify them integer, string, and decimal. But in Python no need to specify. We can declare variables like Example: C# or Java int age = 28; string Name = "Siddhu"; Example: Python age = 28 Name = "Siddhu" So, you don't need to declare variable types in python. This is an advantage in Python, But still have few Disadvantages too. Example: In my Python function def add_numbers(x,y): print(x+y) add_numbers(20,50) //Output: 70 add_numbers(20,"Something") //Error:"Traceback (most recent call last): File "C:/Users/siddhartha.e/PycharmProjects/siddhu-py/my1stpycode.py", line 8, in add_numbers(50,"Something") File "C:/Users/siddhartha.e/PycharmProjects/siddhu-py/my1stpycode.py", line 4, in add_numbers print(a + b) TypeError: unsupported operand type(s) for +: 'int' and 'str'" ...

Database and Migrations

Database and Migrations You can config Database in the .env file. By default, Laravel has MySQL configuration. For example, I configured my details DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=Laravel_tutorials DB_USERNAME=root DB_PASSWORD= So how it connects the database, In your root folder config/database.php file will read the .env file configuration. Migrations: Migrations are most likely a version control for your database. Advantages You can easily allow your team to modify database schema and share to everyone in the application No headache to add a new column in the database manually. This migration will help all teammates into one path. Now check with artisan command php artisan migrate php artisan migrate This command will create basic users,password_resets and migrations tables. Here migrations table will track of all migrates You can undo previous migration using rollback command php artisan ...

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', ...