Using "magic numbers" and doing a lot of math with dates makes your code less readable, and also can cause problems - it doesn't deal well with leapyears, daylight savings time, time zones, or all the other weirdness that comes with dates and time.
When possible, you should always use helper functions like strtotime() to deal with dates and avoid doing math directly.
Here's my shot at doing what you want, it's not perfect (you can't add a time period larger than the gap between two periods - that is, 14 hours from 18:30 to 8:30 - and it still uses some raw math, but it's an improvement:
<?php
function addRollover($givenDate, $addtime) {
$starttime = 8.5*60; //Start time in minutes (decimal hours * 60)
$endtime = 18.5*60; //End time in minutes (decimal hours * 60)
$givenDate = strtotime($givenDate);
//Get just the day portion of the given time
$givenDay = strtotime('today', $givenDate);
//Calculate what the end of today's period is
$maxToday = strtotime("+$endtime minutes", $givenDay);
//Calculate the start of the next period
$nextPeriod = strtotime("tomorrow", $givenDay); //Set it to the next day
$nextPeriod = strtotime("+$starttime minutes", $nextPeriod); //And add the starting time
//If it's the weekend, bump it to Monday
if(date("D", $nextPeriod) == "Sat") {
$nextPeriod = strtotime("+2 days", $nextPeriod);
}
//Add the time period to the new day
$newDate = strtotime("+$addtime", $givenDate);
//print "$givenDate -> $newDate\n";
//print "$maxToday\n";
//Get the new hour as a decimal (adding minutes/60)
$hourfrac = date('H',$newDate) + date('i',$newDate)/60;
//print "$hourfrac\n";
//Check if we're outside the range needed
if($hourfrac < $starttime || $hourfrac > $endtime) {
//We're outside the range, find the remainder and add it on
$remainder = $newDate - $maxToday;
//print "$remainder\n";
$newDate = $nextPeriod + $remainder;
}
return $newDate;
}
?>
I've commented out the print statements I had for debugging, you can uncomment them if you want to see how it works (which I recommend!)
You use it as such:
<?php
print date('Y-m-d H:i:s',addRollover('2013-01-01 17:30','2 hours')) . "\n";
print date('Y-m-d H:i:s',addRollover('2013-01-01 18:00','3 hours')) . "\n";
print date('Y-m-d H:i:s',addRollover('2013-01-04 17:00','150 minutes')) . "\n";
?>
Results in:
2013-01-02 09:30:00
2013-01-02 11:00:00
2013-01-07 09:30:00
This code should deal just fine with most weirdnesses of dates, such as timezones, daylight savings, and such. It would be even better implemented with PHP's DateTime class, but that is fairly new and I'm not as familiar with it, so I stuck with strtotime().