Calculating working hours between two dates

Related searches

I need a PHP method for calculating working hours between two dates based on a 8 hour working day and excluding weekends and bank holidays.

For example the difference between 2012-01-01T08:30:00 AND 2012-01-05T10:30:00 in working hours is actually 26 working hours because the first two days are weekend/bank holiday which just leaves 3 working days and the time differnce of 2 hours i.e. 3*8+2=26.

I have used @flamingLogos excellent answer to a previous question but cannot get it to take into account the time as well as date.

Function below calculates working hours between two dates, provided in text format such as '2013-11-27 13:40', taking work day hours from 9 to 17 (can be changed).

function get_working_hours($from,$to)
{
    // timestamps
    $from_timestamp = strtotime($from);
    $to_timestamp = strtotime($to);

    // work day seconds
    $workday_start_hour = 9;
    $workday_end_hour = 17;
    $workday_seconds = ($workday_end_hour - $workday_start_hour)*3600;

    // work days beetwen dates, minus 1 day
    $from_date = date('Y-m-d',$from_timestamp);
    $to_date = date('Y-m-d',$to_timestamp);
    $workdays_number = count(get_workdays($from_date,$to_date))-1;
    $workdays_number = $workdays_number<0 ? 0 : $workdays_number;

    // start and end time
    $start_time_in_seconds = date("H",$from_timestamp)*3600+date("i",$from_timestamp)*60;
    $end_time_in_seconds = date("H",$to_timestamp)*3600+date("i",$to_timestamp)*60;

    // final calculations
    $working_hours = ($workdays_number * $workday_seconds + $end_time_in_seconds - $start_time_in_seconds) / 86400 * 24;

    return $working_hours;
}

There are two additional functions. One returns work days array...

function get_workdays($from,$to) 
{
    // arrays
    $days_array = array();
    $skipdays = array("Saturday", "Sunday");
    $skipdates = get_holidays();

    // other variables
    $i = 0;
    $current = $from;

    if($current == $to) // same dates
    {
        $timestamp = strtotime($from);
        if (!in_array(date("l", $timestamp), $skipdays)&&!in_array(date("Y-m-d", $timestamp), $skipdates)) {
            $days_array[] = date("Y-m-d",$timestamp);
        }
    }
    elseif($current < $to) // different dates
    {
        while ($current < $to) {
            $timestamp = strtotime($from." +".$i." day");
            if (!in_array(date("l", $timestamp), $skipdays)&&!in_array(date("Y-m-d", $timestamp), $skipdates)) {
                $days_array[] = date("Y-m-d",$timestamp);
            }
            $current = date("Y-m-d",$timestamp);
            $i++;
        }
    }

    return $days_array;
}

and second - returns holidays array

function get_holidays() 
{
    // arrays
    $days_array = array();

    // You have to put there your source of holidays and make them as array...
    // For example, database in Codeigniter:
    // $days_array = $this->my_model->get_holidays_array();

    return $days_array;
}

Excel formula: Get work hours between dates and times, To calculate total work hours between two dates and times, you can use a formula based on the NETWORKDAYS function. To calculate the total number of work hours between two dates, you can use a formula based on the NETWORKDAYS function, where "start" is the start date, "end" is the end date, "holidays" is a range that includes dates, and "hours" is the number of work hours in a workday. In the example shown, the formula in D7 is: =

Maybe you can use this function :

function work_hours_diff($date1,$date2) {
    if ($date1>$date2) { $tmp=$date1; $date1=$date2; $date2=$tmp; unset($tmp); $sign=-1; } else $sign = 1;
    if ($date1==$date2) return 0;

    $days = 0;
    $working_days = array(1,2,3,4,5); // Monday-->Friday
    $working_hours = array(8.5, 17.5); // from 8:30(am) to 17:30
    $current_date = $date1;
    $beg_h = floor($working_hours[0]); $beg_m = ($working_hours[0]*60)%60;
    $end_h = floor($working_hours[1]); $end_m = ($working_hours[1]*60)%60;

    // setup the very next first working timestamp

    if (!in_array(date('w',$current_date) , $working_days)) {
        // the current day is not a working day

        // the current timestamp is set at the begining of the working day
        $current_date = mktime( $beg_h, $beg_m, 0, date('n',$current_date), date('j',$current_date), date('Y',$current_date) );
        // search for the next working day
        while ( !in_array(date('w',$current_date) , $working_days) ) {
            $current_date += 24*3600; // next day
        }
    } else {
        // check if the current timestamp is inside working hours

        $date0 = mktime( $beg_h, $beg_m, 0, date('n',$current_date), date('j',$current_date), date('Y',$current_date) );
        // it's before working hours, let's update it
        if ($current_date<$date0) $current_date = $date0;

        $date3 = mktime( $end_h, $end_m, 59, date('n',$current_date), date('j',$current_date), date('Y',$current_date) );
        if ($date3<$current_date) {
            // outch ! it's after working hours, let's find the next working day
            $current_date += 24*3600; // the day after
            // and set timestamp as the begining of the working day
            $current_date = mktime( $beg_h, $beg_m, 0, date('n',$current_date), date('j',$current_date), date('Y',$current_date) );
            while ( !in_array(date('w',$current_date) , $working_days) ) {
                $current_date += 24*3600; // next day
            }
        }
    }

    // so, $current_date is now the first working timestamp available...

    // calculate the number of seconds from current timestamp to the end of the working day
    $date0 = mktime( $end_h, $end_m, 59, date('n',$current_date), date('j',$current_date), date('Y',$current_date) );
    $seconds = $date0-$current_date+1;

    printf("\nFrom %s To %s : %d hours\n",date('d/m/y H:i',$date1),date('d/m/y H:i',$date0),$seconds/3600);

    // calculate the number of days from the current day to the end day

    $date3 = mktime( $beg_h, $beg_m, 0, date('n',$date2), date('j',$date2), date('Y',$date2) );
    while ( $current_date < $date3 ) {
        $current_date += 24*3600; // next day
        if (in_array(date('w',$current_date) , $working_days) ) $days++; // it's a working day
    }
    if ($days>0) $days--; //because we've allready count the first day (in $seconds)

    printf("\nFrom %s To %s : %d working days\n",date('d/m/y H:i',$date1),date('d/m/y H:i',$date3),$days);

    // check if end's timestamp is inside working hours
    $date0 = mktime( $beg_h, 0, 0, date('n',$date2), date('j',$date2), date('Y',$date2) );
    if ($date2<$date0) {
        // it's before, so nothing more !
    } else {
        // is it after ?
        $date3 = mktime( $end_h, $end_m, 59, date('n',$date2), date('j',$date2), date('Y',$date2) );
        if ($date2>$date3) $date2=$date3;
        // calculate the number of seconds from current timestamp to the final timestamp
        $tmp = $date2-$date0+1;
        $seconds += $tmp;
        printf("\nFrom %s To %s : %d hours\n",date('d/m/y H:i',$date2),date('d/m/y H:i',$date3),$tmp/3600);
    }

    // calculate the working days in seconds

    $seconds += 3600*($working_hours[1]-$working_hours[0])*$days;

    printf("\nFrom %s To %s : %d hours\n",date('d/m/y H:i',$date1),date('d/m/y H:i',$date2),$seconds/3600);

    return $sign * $seconds/3600; // to get hours
}

I put printf() to show what it is done (you can remove them)

You call it like that :

date_default_timezone_set("America/Los_Angeles");
$dt2 = strtotime("2012-01-01 05:25:00");
$dt1 = strtotime("2012-01-19 12:40:00");
echo work_hours_diff($dt1 , $dt2 );

Excel formula: Get work hours between dates, To calculate total work hours between two dates and times, you can use a formula based on the NETWORKDAYS function. In the example shown, E5 contains this� In order to calculate the net work hours between two dates, we need to have some information to start with. Here are the variables necessary to make the net work hours formula work. $Start_Time– This is the time that the work day starts, as an Excel-formatted time. (e.g. 9:00AM) No date should be attached.

The other two proposals don't work if you choose start or end in a non-working day or time. This are the results my code gets using a working day of 9:00 to 20:00 and rest days Saturday and Sunday.

get_working_hours('2016-10-08 08:00:00', '2016-10-08 21:00:00'); //Saturday: 0 hrs
get_working_hours('2016-10-10 08:00:00', '2016-10-10 21:00:00'); //Monday: 11 hrs
get_working_hours('2016-10-10 10:00:00', '2016-10-10 19:00:00'); //Monday: 9 hrs
get_working_hours('2016-10-07 19:00:00', '2016-10-10 10:00:00'); //fri-mon: 2 hrs
get_working_hours('2016-10-08 19:00:00', '2016-10-10 10:00:00'); //sat-mon: 1 hrs
get_working_hours('2016-10-07 19:00:00', '2016-10-09 10:00:00'); //fri-sun: 1 hrs

function get_working_hours($ini_str,$end_str){
    //config
    $ini_time = [9,0]; //hr, min
    $end_time = [20,0]; //hr, min
    //date objects
    $ini = date_create($ini_str);
    $ini_wk = date_time_set(date_create($ini_str),$ini_time[0],$ini_time[1]);
    $end = date_create($end_str);
    $end_wk = date_time_set(date_create($end_str),$end_time[0],$end_time[1]);
    //days
    $workdays_arr = get_workdays($ini,$end);
    $workdays_count = count($workdays_arr);
    $workday_seconds = (($end_time[0] * 60 + $end_time[1]) - ($ini_time[0] * 60 + $ini_time[1])) * 60;
    //get time difference
    $ini_seconds = 0;
    $end_seconds = 0;
    if(in_array($ini->format('Y-m-d'),$workdays_arr)) $ini_seconds = $ini->format('U') - $ini_wk->format('U');
    if(in_array($end->format('Y-m-d'),$workdays_arr)) $end_seconds = $end_wk->format('U') - $end->format('U');
    $seconds_dif = $ini_seconds > 0 ? $ini_seconds : 0;
    if($end_seconds > 0) $seconds_dif += $end_seconds;
    //final calculations
    $working_seconds = ($workdays_count * $workday_seconds) - $seconds_dif;
    echo $ini_str.' - '.$end_str.'; Working Hours:'.($working_seconds / 3600).b();
    return $working_seconds / 3600; //return hrs
}

function get_workdays($ini,$end){
    //config
    $skipdays = [6,0]; //saturday:6; sunday:0
    $skipdates = []; //eg: ['2016-10-10'];
    //vars
    $current = clone $ini;
    $current_disp = $current->format('Y-m-d');
    $end_disp = $end->format('Y-m-d');
    $days_arr = [];
    //days range
    while($current_disp <= $end_disp){
        if(!in_array($current->format('w'),$skipdays) && !in_array($current_disp,$skipdates)){
            $days_arr[] = $current_disp;
        }
        $current->add(new DateInterval('P1D')); //adds one day
        $current_disp = $current->format('Y-m-d');
    }
    return $days_arr;
}

Business Days Calculator – Count Workdays, Business Days Calculator counts the number of days between two dates, with the option of excluding weekends and public holidays. Calculate working hours exclude weekends/holidays. If you want to calculate the net working hours excluding weekends or holidays, you can do as bellow: Calculate net working hours exclude weekends. 1. Select two cells and format them as custom format m/d/yyyy h:mm, and enter the start date time and end date time. See screenshot: 2.

Time Duration Calculator: Time between two dates/times, Time Calculator: Duration Between Two Times and Dates. How many years, months, days, hours, minutes, and seconds are there between two moments in time� I need a PHP method for calculating working hours between two dates based on a 8 hour working day and excluding weekends and bank holidays. For example the difference between 2012-01-01T08:30:00 AND 2012-01-05T10:30:00 in working hours is actually 26 working hours because the first two days are weekend/bank holiday which just leaves 3 working days and the time differnce of 2 hours i.e. 3*8+2=26 .

Purpose: This function will return working hours between given 2 dates. This function assumes that the break is between 9:45 AM and 10 AM and that Lunch is between 12:30 PM and 1 PM.

I tried to do as you suggested, but considering the example below, as January 12th and 13th are not working days, being the Start Date "11-Jan-2019 11:55" and the End Date "14-Jan-2019 9:30", I'd like for the calculation to count the hours between Jan11 from 11:55 to 18:00, and Jan14 from 08:00 to 09:30, resulting on 7.57 hours (or 7hours and

Comments
  • What time does the 8 hour working day start and end?
  • The working day is 8.30-5.30.
  • Excellent excellent code, hajlabajla ! One wonders though, if there is an elegant way to use half day (0900-1300) for saturdays
  • I do not think this works. $start = '2019-09-03 12:00'; $end = '2019-09-03 20:00'; $a = $support->getWorkingHours($start, $end ); $workday_start_hour = 0; $workday_end_hour = 17; I am expecting 5 hours however I am getting 8 hours