以 PHP 计算工作时间时差

我想计算编码日期和完成日期之间的小时数。截至目前,我可以计算两个日期时间之间的时差,不包括星期六和星期日。我的问题是我需要排除午休时间(上午12:00至下午1:00)和假期。


这是我的代码:


<?php

function business_hours($start, $end){


    $startDate = new DateTime($start);

    $endDate = new DateTime($end);

    $periodInterval = new DateInterval( "PT1H" );


    $period = new DatePeriod( $startDate, $periodInterval, $endDate );

    $count = 0;


    $holidays = [

      "Human Rights Day"      => new DateTime(date('Y') . '-03-21'),

      "Good Friday"           => new DateTime(date('Y') . '-03-30'),

      "Family Day"            => new DateTime(date('Y') . '-04-02'),

      "Freedom Day"           => new DateTime(date('Y') . '-04-27'),

      "Labour Day"            => new DateTime(date('Y') . '-05-01'),

      "Youth Day"             => new DateTime(date('Y') . '-06-16'),

      "National Women's Day"  => new DateTime(date('Y') . '-08-09'),

      "Heritage Day"          => new DateTime(date('Y') . '-09-24'),

      "Day of Reconciliation" => new DateTime(date('Y') . '-12-16'),

    ];


    foreach($period as $date){


    $startofday = clone $date;

    $startofday->setTime(8,00);


    $endofday = clone $date;

    $endofday->setTime(17,00);


        if($date > $startofday && $date <= $endofday && !in_array($date->format('l'), array('Sunday','Saturday'))){

            $count++;

        }


    }

    echo $count;

}


$start = '2020-02-14 08:00:00';

$end = '2020-02-17 08:00:00';


$go = business_hours($start,$end);


//output 9 hours

?>

根据我的代码,我将工作时间设置为8:00至17:00,然后排除了周六和周日。根据我的例子,输出将为9(包括午休时间)。如何排除午休和节假日?


更新


完成时间可以超过 1 天。例如,开始日期/时间为 2020-02-14 08:00:00,完成时间为 2020-02-19 08:00:00,输出为 27 小时。计算应排除每天中午12:00至下午1:00的午休时间以及介于两者之间的假期。


更新

我添加了一系列假期,如何排除这些假期?


陪伴而非守候
浏览 216回答 2
2回答

HUX布斯

由于您使用的是静态/定义的午休时间,因此可以使用以下逻辑:如果$startDate是工作日,并且在12:00之前,则为午餐计算的开始日期;否则就是下一个工作日。如果$endDate是工作日,13:00之后,则为午餐计算的结束日期;否则,是前一个工作日实际午休时间数等于这些重新计算的日期之间的差额,每个日期一小时。以下是伪代码:&nbsp; &nbsp;if(!in_array($startDate->format('l'), array('Sunday','Saturday')) && ($startDate->format('g') < 12) {&nbsp; &nbsp; &nbsp; &nbsp; $startForLunch = $startDate;&nbsp; &nbsp; }&nbsp; &nbsp; else {&nbsp; &nbsp; &nbsp; &nbsp; $startForLunch = new DateTime($start, '+1 day');&nbsp; &nbsp; &nbsp; &nbsp; while(in_array($startDate->format('l'), array('Sunday','Saturday'))){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $startForLunch->add('1 day');&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; if(!in_array($endDate->format('l'), array('Sunday','Saturday')) && ($endDate->format('g') > 13) {&nbsp; &nbsp; &nbsp; &nbsp; $endForLunch = $end;&nbsp; &nbsp; }&nbsp; &nbsp; else {&nbsp; &nbsp; &nbsp; &nbsp; $endForLunch = new DateTime($endDate, '-1 day');&nbsp; &nbsp; &nbsp; &nbsp; while(in_array($endDate->format('l'), array('Sunday','Saturday'))){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $endForLunch->add('-1 day');&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; $lunchPeriods = $endForLunch - $startForLunch + 1;

汪汪一只猫

尝试每天在循环中添加一些条件以跳过几个小时怎么样?($date->format('H') <= 12 || $date->format('H') > 13)如果小时高于12到13,它将跳过(如果您使用24格式小时)if($date > $startofday && $date <= $endofday && !in_array($date->format('l'), array('Sunday','Saturday')) && ($date->format('H') <= 12 || $date->format('H') > 13)){&nbsp; &nbsp;$count++;}更新好吧,如果你的“圣日”是cutom,也许最好在你的功能中添加一些参数来存储你的圣日列表function business_hours($start, $end,$holyDays = null){&nbsp; //another line}并检查每个日期循环是否在圣日列表中in_array($date->format('Y-m-d'), $holyDays)您将获得休息时间和自定义圣日的过滤器function business_hours($start, $end,$holyDays = null){&nbsp; &nbsp; $startDate = new DateTime($start);&nbsp; &nbsp; $endDate = new DateTime($end);&nbsp; &nbsp; $periodInterval = new DateInterval( "PT1H" );&nbsp; &nbsp; $period = new DatePeriod( $startDate, $periodInterval, $endDate );&nbsp; &nbsp; $count = 0;&nbsp; &nbsp; foreach($period as $date){&nbsp; &nbsp; &nbsp; &nbsp; $startofday = clone $date;&nbsp; &nbsp; &nbsp; &nbsp; $startofday->setTime(8,00);&nbsp; &nbsp; &nbsp; &nbsp; $endofday = clone $date;&nbsp; &nbsp; &nbsp; &nbsp; $endofday->setTime(17,00);&nbsp; &nbsp; &nbsp; &nbsp; //just some var to use in conditional check&nbsp; &nbsp; &nbsp; &nbsp; $notHolyday = true;&nbsp; &nbsp; &nbsp; &nbsp; //now check the array of holyday and check if in range dates is same with holydays we have&nbsp; &nbsp; &nbsp; &nbsp; if($holyDays != null && is_array($holyDays) && in_array($date->format('Y-m-d'), $holyDays)){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $notHolyday = false;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; if($date > $startofday && $date <= $endofday && !in_array($date->format('l'), array('Sunday','Saturday')) && ($date->format('H') <= 12 || $date->format('H') > 13) && $notHolyday){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $count++;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; echo $count;}$start = '2020-02-14 08:00:00';$end = '2020-02-19 08:00:00';$holyDays = array('2020-02-17','2020-02-18');$count = business_hours($start,$end,$holyDays);echo $count;我希望这是你想要的
打开App,查看更多内容
随时随地看视频慕课网APP