基本上,我正在尝试创建一个基本的案件记录系统,当有人打开一个新案件时,该案件被分配一个给定小时数的优先级。例如优先级1为4小时,2为9小时,3为36小时,4为63小时。
现在在时间戳上添加时间很容易,但问题是我需要考虑周一到周五的08:30到17:30的工作时间。因此,如果一个案件被给予4小时的优先处理时间,而截止日期是在工作日的17:30之后,那么截止日期就会延长到下一个工作日。基本上截止时间是4个工作小时。
的例子:
案例创建日期:19/05/2014 16:55 -优先级为1(4小时)截止日期:20/05/2014 11:55
有意义吗?
另一个问题是我需要考虑待机时间,这两个必须只在工作时间内。但是我以后再担心。
我尽量使用现代的DateTime类。
这是我到目前为止所拥有的,我正在与逻辑斗争。如果截止日期在一天之内,它可以工作,但如果我增加63个小时,它会在周日返回。
我哪里错了?脑子被这个炸了:(
<?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');
实际操作:http://3v4l.org/Ac8ro
下面是对函数中应该发生的事情的解释:
首先,我们创建一个DateTime对象,表示开始日期/时间
然后添加指定的时间(参见支持的日期和时间格式)
我们检查是否在周末,下午6点以后,或者在下午5点超过30个小时过了几分钟(例如下午5:30以后)
如果是,我们克隆datetime对象并将其设置为5:30PM
然后将结束时间(5:30PM)与修改后的时间之间的差值作为DateInterval对象
然后继续到第二天
如果第二天是星期六,我们继续到第二天
如果第二天是星期天,我们继续到第二天
然后将时间设置为8:30AM
然后将结束时间(5:30PM)和修改后的时间之间的差值添加到datetime对象
从函数
UPDATE 2
根据提供的建议更新了代码
<?php
function addRollover($givenDate, $addtime, $dayStart, $dayEnd, $weekDaysOnly) {
//Break the working day start and end times into hours, minuets
$dayStart = explode(',', $dayStart);
$dayEnd = explode(',', $dayEnd);
//Create required datetime objects and hours interval
$datetime = new DateTime($givenDate);
$endofday = clone $datetime;
$endofday->setTime($dayEnd[0], $dayEnd[1]); //set end of working day time
$interval = 'PT'.$addtime.'H';
//Add hours onto initial given date
$datetime->add(new DateInterval($interval));
//if initial date + hours is after the end of working day
if($datetime > $endofday)
{
//get the difference between the initial date + interval and the end of working day in seconds
$seconds = $datetime->getTimestamp()- $endofday->getTimestamp();
//Loop to next day
while(true)
{
$endofday->add(new DateInterval('PT24H'));//Loop to next day by adding 24hrs
$nextDay = $endofday->setTime($dayStart[0], $dayStart[1]);//Set day to working day start time
//If the next day is on a weekend and the week day only param is true continue to add days
if(in_array($nextDay->format('l'), array('Sunday','Saturday')) && $weekDaysOnly)
{
continue;
}
else //If not a weekend
{
$tmpDate = clone $nextDay;
$tmpDate->setTime($dayEnd[0], $dayEnd[1]);//clone the next day and set time to working day end time
$nextDay->add(new DateInterval('PT'.$seconds.'S')); //add the seconds onto the next day
//if the next day time is later than the end of the working day continue loop
if($nextDay > $tmpDate)
{
$seconds = $nextDay->getTimestamp()-$tmpDate->getTimestamp();
$endofday = clone $tmpDate;
$endofday->setTime($dayStart[0], $dayStart[1]);
}
else //else return the new date.
{
return $endofday;
}
}
}
}
return $datetime;
}
$currentTime = '2014-06-27 08:30:00';
$dayStart = '8,30';
$dayEnd = '17,30';
$future = addRollover($currentTime, 65, $dayStart, $dayEnd, true);
echo "Results: </br>";
echo $future->format('Y-m-d H:i:s').'</br>';