DateTime类创建一个函数,在考虑到工作时间和保持时间的情况下,在截止日期前添加小时 [英] DateTime class create a function to add hours onto a deadline taking into account working hours and on hold time

查看:170
本文介绍了DateTime类创建一个函数,在考虑到工作时间和保持时间的情况下,在截止日期前添加小时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

基本上,我正在尝试创建一个基本的案件记录系统,当有人打开一个新案件时,该案件被分配了给定的小时数优先级.例如,优先级1是4小时,2是9小时,3是36小时,4是63小时.

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.

现在将时间添加到时间戳上很容易,但是要注意的是,我需要考虑周一至周五的08:30至17:30的工作时间.因此,如果将一个案例的优先级设为4小时,并且截止日期为工作日的17:30之后,则截止日期将延长至下一个工作日.截止日期基本上是4个工作小时.

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.

示例:

案例创建于:19/05/2014 16:55-优先级1(4小时) 截止日期为:20/05/2014 11:55

Case created on: 19/05/2014 16:55 - with Priority 1 (4 Hours) Deadline is now: 20/05/2014 11:55

有道理吗?

另一个问题是我需要考虑保留时间,而这两个时间只能在工作时间之内.但是以后会担心.

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.

我正在尝试为此使用现代的DateTime类.

I am trying to use the modern DateTime class for this as far as possible.

到目前为止,这是我所要解决的问题,我在逻辑上苦苦挣扎.如果截止日期是一天之内,它会起作用,但是如果我添加了63个小时,它将在星期日返回.

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');

查看实际运行情况: http://3v4l.org/Ac8ro

以下是该函数应该发生的情况的说明:

Here's an explanation of what's supposed to be going on in the function:

首先,我们创建一个代表开始日期/时间的DateTime对象

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)

我们检查一下是周末,下午6点之后还是下午5点(超过30点) 分钟过去了(例如,下午5:30之后)

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)

如果是这样,我们克隆日期时间对象并将其设置为5:30 PM

If so we clone our datetime object and set it to 5:30PM

然后,我们将结束时间(5:30 PM)与修改后的时间之间的差值作为DateInterval对象获取

We then get the difference between the end time (5:30PM) and the modified time as a DateInterval object

然后我们进行到第二天

如果第二天是星期六,我们将进行到第二天

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

然后我们将时间设置为8:30 AM

We then set our time to 8:30AM

然后,将结束时间(5:30 PM)与修改后的时间之间的差值添加到datetime对象

We then add our difference between the end time (5:30PM) and the modified time to our datetime object

我们从函数中返回对象

推荐答案

更新2

根据提供的建议更新了代码

UPDATE 2

Updated the code as per based on suggestions provided

<?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>';

这篇关于DateTime类创建一个函数,在考虑到工作时间和保持时间的情况下,在截止日期前添加小时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆