PHP Time Manipulation

Hi Chaps,
I have a MySQL (Y-m-d H:i:s) starting date. . .
I then have a task duration in seconds/minutes
What I’m after is a task ‘due’ date, which falls between normal working hours (09:00 - 17:30).

$task_start = 2010-05-27 16:08:23;
$duration = 45000; // Which I guess is 12.5 hours????
$start_str = strtotime($task_start);
$calc = $start_str + $duration;
$due_date = date('Y-m-d H:i:s', $calc);
echo $due_date; // 2010-05-28 04:38:23

As you can see, the calculation is correct, but the time falls outside the normal working hours, so I need some sort of function to check, then re-calculate so it falls between 09:00-17:30.

Any help would be awesome!

I have not tested this, but this is how it occured to my mind to do it; reduce everything to seconds.


$start = time(); //or strtotime(YourstartDateHere)
$curday = date('w',$start) - 1;
$duration = somenumber; //How Long Will It Take?
$expanse = (strtotime('17:30:00') - strtotime(date('H:i:s',$start) > $duration) ? strtotime('17:30:00') - strtotime(date('H:i:s',$start) : $duration;
$duration -= (strtotime('17:30:00') - strtotime(date('H:i:s',$start) > $duration) ? strtotime('17:30:00') - strtotime(date('H:i:s',$start) : $duration;
if ($duration > 0) {
  $expanse += 23400; //Move time to Midnight; Start New Day.
}
while($duration > 30600) {
  $curday++;
  $expanse += 86400; //Add a day
  $duration -= 30600; //Subtract a day's work
  if($curday == 5) {
   $curday = 0;
   $expanse += 172800; //Add a Weekend
  }
}
if ($duration > 0) {
  $curday++;
  if($curday == 5) {
   $expanse += 172800; //Add a Weekend
  }
  $expanse += 32400 + $duration;
}
$task_due = date('Y-m-d H:i:s',($start+$expanse));

I now have this code, that will calculate the correct times, but does anyone know how I can check to see if the correct time falls on a weekend, and if so, move it to the next Monday?

$task_start = "2010-05-27 16:08:23";
        $duration = 45000; // Which I guess is 12.5 hours????
        $start_str = strtotime($task_start);

        $calc = $start_str + $duration;
        $due_date = date('Y-m-d H:i:s',$calc);

        $test_date=$calc;
        $test_endtime=strtotime(date("Y-m-d",$start_str )." 17:30"); //start date 17:30
        $test_starttime=strtotime(date("Y-m-d",$start_str+3600*24)." 9:00"); //next date 9:00

        while ($test_date > $test_endtime)
        {
                $diff=$test_date - $test_endtime;
                $test_date=$test_starttime + $diff;
                $test_endtime+=3600*24;
                $test_starttime+=3600*24;
        }

        echo "<br>".$due_date; // 2010-05-28 04:38:23
        echo "<br>".date('Y-m-d H:i:s',$test_date) //2010-05-29 11:38:23

$task_due = date('Y-m-d H:i:s',$test_date);

If your working hours is from 9am to 5.30pm that leaves 8.5 hours of work each day. Though if we remove lunch we would be around 8 hours, in addition you might need to remove another 30-60min depending on how accurate you want the available hours to be.

Since we now know that there is eight hours available per work day (Mon-Fri) it allow us to setup a system to manage the time.

First you will find the start time, if this is at 1pm you know there is another 4.5 hours left that day, so if the duration is 6 hours you need to put the remaining 1.5 hours on another day. After you have put the 4.5 hours on the first day, you locate the second day and put the remaining 1.5 hours from 8am. Now make certain that you verify if the first day was a Friday and if move the next day to Monday (Same way you might want to setup a system to locate national holidays etc).

I dont have the time to give you the ready made solution in php, but with the explanation of the process above I am certain that you will manage to put this together.

Good luck!

Hi RedDevil, thanks for the reply
I have this code, but I think it’s a bit muddled with the units being used . . could you take a look and see if this makes sense???

if(date('Hi', $calc) > 1730) {
	// find out how much work will be done until 1730
	$first_hours = 1730 - date('Hi', $start_str);
	// find out the remaining duration
	$next_hours = $duration - $first_hours;
	// calculate the due time, starting from 9:00AM / 28800 (Unix) 
	$next_time = date('H:i', 28800 + $next_hours);
	// show the due date
	$due = strtotime("next day $next_time", $start_str);
	$task_due = date('Y-m-d H:i:s', $due);
}

This doesn’t take into account any due_date that goes past 23:59, onto the next day (e.g. due_date = 04:30), so I need
A: get the above working,
B: apply similar logic to accommodate over-runs
C: loop through A/B until due_date is within working-hours (or is this over-kill???)