Search code examples
phpdeadlines

Define the due date from a ticket creation date php


I am building a SLA KPI. The SLA is based on ticket type and priority, each of these have a due date.

The thing is, I only have the field created_at, I don't have this due date, so I need to calculate it, and as mentioned above, use the params priority and type to define the right date.

But my real problem is, how to calculate it on PHP, considering operation days and hours, monday to friday, 8:00 to 18:00 For example.

The ticket was created at 2019-06-04 08:00:00 and its deadline is 16 hours. So it would be, 2019-06-06 08:00:00


Solution

  • After digging a lot looking for a answer, I've found a function that solved my problem.

        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;
    }
    

    Thank you all.