0

Lets say I have the following daterange:

2014-01-10 11:00 - 2014-01-13 15:00

I also know that I can only count the hours between 09:00 - 16:00, how do I achieve this with PHP?

The above daterange should give me 25 hours (5 + 7 + 7 + 6), not sure how such PHP-function should look, though.

Undrium
  • 2,558
  • 1
  • 16
  • 24

2 Answers2

4

Completely untested, without any varatny

<?php
$time1 = new DateTime("11:00");
$time2 = new DateTime("15:00");
$date1 = new DateTime("2014-01-10");
$date2 = new DateTime("2014-01-13");

$start = new DateTime("9:00");
$end = new DateTime("16:00");

$maxperday = $end->diff($start)->format("%h");
$full_day_hours = ($date2->diff($date1)->format("%a")-1)*$maxperday;
$first_day_hours = min($maxperday,max(0,$end->diff($time1)->format("%h")));
$last_day_hours = min($maxperday,max(0,$time2->diff($start)->format("%h")));

$hours = $first_day_hours + $full_day_hours + $last_day_hours;
?>

EDIT: Tested now, corrected two errors, seems to work now.

Alexander
  • 19,906
  • 19
  • 75
  • 162
  • It fulfils your specification, so I guess you should rework them... :) – Alexander Jan 30 '14 at 13:38
  • Problem occurs when you just have two days in the range, and the last day ends before the start-time. The dates I'm using in the specification are of course arbitrary and should be changable. 2014-01-10 11:00 to 2014-01-11 08:00 won't work for instance. – Undrium Jan 30 '14 at 13:50
0

I have made a solution now, but not too happy with my calculation if it is just one day. Here is the code:

$startDate = strtotime("2014-01-22 15:00");
$endDate = strtotime("2014-01-24 18:00");

$time1 = new DateTime(date("H:i", $startDate));
$time2 = new DateTime(date("H:i", $endDate));
$date1 = new DateTime(date("Y-m-d", $startDate));
$date2 = new DateTime(date("Y-m-d", $endDate));

$start = new DateTime("11:00");
$end = new DateTime("18:00");

$maxPerDay = $end->diff($start)->format("%h") != 0 ? $end->diff($start)->format("%h") : 24;
$days = $date2->diff($date1)->format("%a");

$hours = 0; 
//Is it just one day and is time intersecting?
if($days == 0 && ($start <= $time2 && $time1 <= $end)){
    $hours = $maxPerDay;
    if($start < $time1 || $end > $time2){
        if($time1 < $start){
            $hours = $maxPerDay - $time2->diff($end)->format("%h");
        }else if($time2 > $end){
            $hours = $maxPerDay - $time1->diff($start)->format("%h");
        }else{
            $hours = $time1->diff($time2)->format("%h");
        }
    }
}else if($days > 0){
    $firstDay = 0;
    $lastDay = 0;
    if($time1 < $end){
        $firstDay = $time1 < $start ? $maxPerDay : $maxPerDay - $time1->diff($start)->format("%h"); 
    }
    if($time2 > $start){
        $lastDay = $time2 > $end ? $maxPerDay : $maxPerDay - $time2->diff($end)->format("%h");
    }
    $hours = $lastDay + $firstDay + ($days - 1) * $maxPerDay;
}

echo $hours;
Undrium
  • 2,558
  • 1
  • 16
  • 24