以秒为单位计算时间差,不包括周末和PHP中的时间段

时间:2014-08-18 13:06:14

标签: php mysql date datetime

我已经放弃尝试在MySQL中执行此操作,而是将结果注入到我的结果数组中(稍后在JS应用程序中使用)。

我有一个循环来完成每个结果:

$data = $result->fetchAll();

foreach($data as $i => $row) {
    // Something                    
    $data[$i]['Age'] = $row['Age'];
}

我希望它将$data[$i]['Age'](日期时间)与当前日期时间之间的秒数相加。

通常这很容易,但如何在16:30和07:30之间排除周末和时间?

1 个答案:

答案 0 :(得分:0)

我不认为这太具体或无趣,所以这是答案,感谢我的一位同事:

public static function calculateTime($startDate, $endDate) {//Returns Seconds Passed

        date_default_timezone_set('Europe/London');

        //Opening Hours - Can pull from database depending on users working hours

        $workingHoursOpen = new DateTime('07:30:00');

        $workingHoursClose = new DateTime('16:30:00');



        //Time worked from and to

        $timeStarted = strtotime(date('H:i:s', strtotime($endDate)));

        $timeFinished = strtotime(date('H:i:s', strtotime($startDate)));



        $workingSeconds = $workingHoursClose->getTimestamp() - $workingHoursOpen->getTimestamp();

        $workingSecondsv2 = $timeFinished - $timeStarted;



        //Option to send array of holidays (3rd param)

        $workingDays = Util::getWorkingDays(date('Y-m-d', strtotime($startDate)), date('Y-m-d', strtotime($endDate)), array());



        $totalWorkingSeconds = $workingDays * $workingSeconds; //Working days * 9 hours



        $secondsClosed = 0;

        $i = 0;

        while ($i < $workingDays) {

            $secondsClosed = $secondsClosed - (15 * 3600);

            $i++;

        }



        $secondsPassed = ($workingSecondsv2 - $totalWorkingSeconds) + (9 * 3600);



        $secondsPassed = -1 * ($secondsPassed); // Invert number (was giving -XX)



        return $secondsPassed;

    }



    public static function getWorkingDays($startDate, $endDate, $holidays) {

        // do strtotime calculations just once

        $endDate = strtotime($endDate);

        $startDate = strtotime($startDate);



        $days = ($endDate - $startDate) / 86400 + 1;



        $no_full_weeks = floor($days / 7);

        $no_remaining_days = fmod($days, 7);



        //It will return 1 if it's Monday,.. ,7 for Sunday

        $the_first_day_of_week = date("N", $startDate);

        $the_last_day_of_week = date("N", $endDate);



        //---->The two can be equal in leap years when february has 29 days, the equal sign is added here

        //In the first case the whole interval is within a week, in the second case the interval falls in two weeks.

        if ($the_first_day_of_week <= $the_last_day_of_week) {

            if ($the_first_day_of_week <= 6 && 6 <= $the_last_day_of_week)

                $no_remaining_days--;

            if ($the_first_day_of_week <= 7 && 7 <= $the_last_day_of_week)

                $no_remaining_days--;

        }

        else {

            // (edit by Tokes to fix an edge case where the start day was a Sunday

            // and the end day was NOT a Saturday)

            // the day of the week for start is later than the day of the week for end

            if ($the_first_day_of_week == 7) {

                // if the start date is a Sunday, then we definitely subtract 1 day

                $no_remaining_days--;



                if ($the_last_day_of_week == 6) {

                    // if the end date is a Saturday, then we subtract another day

                    $no_remaining_days--;

                }

            } else {

                // the start date was a Saturday (or earlier), and the end date was (Mon..Fri)

                // so we skip an entire weekend and subtract 2 days

                $no_remaining_days -= 2;

            }

        }



        //The no. of business days is: (number of weeks between the two dates) * (5 working days) + the remainder

//---->february in none leap years gave a remainder of 0 but still calculated weekends between first and last day, this is one way to fix it

        $workingDays = $no_full_weeks * 5;

        if ($no_remaining_days > 0) {

            $workingDays += $no_remaining_days;

        }



        //We subtract the holidays

        foreach ($holidays as $holiday) {

            $time_stamp = strtotime($holiday);

            //If the holiday doesn't fall in weekend

            if ($startDate <= $time_stamp && $time_stamp <= $endDate && date("N", $time_stamp) != 6 && date("N", $time_stamp) != 7)

                $workingDays--;

        }



        return $workingDays;

    }

100%工作,可以扩展以从数据库中引入工作时间。