Basically I am trying to create a basic case logging system and when somebody opens a new case, the case is assigned a priority with a given number of hours. For example priority 1 is 4 hours, 2 is 9 hours, 3 is 36hours and 4 is 63 hours.
Now adding hours onto a time stamp is easy but the catch is I need to take into account working hours which are 08:30 to 17:30 Monday to Friday. So if a case is given a 4 hour priority and the deadline for this falls after 17:30 on a week day then the deadline is extended to the next working day. Basically the deadline is 4 working hours.
Example:
Case created on: 19/05/2014 16:55 - with Priority 1 (4 Hours) Deadline is now: 20/05/2014 11:55
Make sense?
Another catch is I need to take into account hours On Hold and these two have to be only within working hours. But ill worry about that later.
I am trying to use the modern DateTime class for this as far as possible.
Here is what I have so far, I am struggling with the logic. It works if the deadline is within a day but if I add something like 63 hours it returns back on a Sunday.
Where am I going wrong here? Brain is fried with this :(
<?php
function addRollover($givenDate, $addtime) {
$datetime = new DateTime($givenDate);
$datetime->modify($addtime);
if (in_array($datetime->format('l'), array('Sunday','Saturday')) ||
17 < $datetime->format('G') ||
(17 === $datetime->format('G') && 30 < $datetime->format('G'))
) {
$endofday = clone $datetime;
$endofday->setTime(17,30);
$interval = $endofday->diff($datetime);
$datetime->add(new DateInterval('P1D'));
if (in_array($datetime->format('l'), array('Saturday', 'Sunday'))) {
$datetime->modify('next Monday');
}
$datetime->setTime(8,30);
$datetime->add($interval);
}
return $datetime;
}
//this is returning back 2014-06-29 17:41:00 which is a sunday.
$future = addRollover('2014-06-26 11:41:00', '+63 hours');
echo $future->format('Y-m-d H:i:s');
See it in action: http://3v4l.org/Ac8ro
Here's an explanation of what's supposed to be going on in the function:
First we create a DateTime object representing our starting date/time
We then add the specified amount of time to it (see Supported Date and Time Formats)
We check to see if it is a weekend, after 6PM, or in the 5PM hour with more than 30 minutes passed (e.g. after 5:30PM)
If so we clone our datetime object and set it to 5:30PM
We then get the difference between the end time (5:30PM) and the modified time as a DateInterval object
We then progress to the next day
If the next day is a Saturday we progress to the next day
If the next day is a Sunday we progress to the next day
We then set our time to 8:30AM
We then add our difference between the end time (5:30PM) and the modified time to our datetime object
We return the object from the function