DateTime类创建一个函数,在截止日期内添加小时数,同时考虑工作时间和保持时间

时间:2014-06-26 09:59:28

标签: php php-5.3 php-5.4

基本上我正在尝试创建一个基本案例记录系统,当有人打开一个新案例时,案例会被分配一个给定小时数的优先级。例如,优先级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:30 PM

然后我们得到结束时间(下午5:30)和修改时间之间的差异作为DateInterval对象

然后我们进入第二天

如果第二天是星期六,我们会进入第二天

如果第二天是星期天,我们会进入第二天

然后我们将时间设定为上午8:30

然后我们将结束时间(下午5:30)和修改时间之间的差异添加到我们的日期时间对象

我们从函数

返回对象

1 个答案:

答案 0 :(得分:0)

更新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>';