Php 如何计算两个日期(不包括节假日和周末)之间的工作时间?
假设我有两个约会:Php 如何计算两个日期(不包括节假日和周末)之间的工作时间?,php,Php,假设我有两个约会: $initialDate = '08/10/2015 09:30:24 am'; $finalDate = '15/10/2015 15:47:38 pm'; $holiday = '12/10/2015'; 我必须考虑一下这些日子的时间。 < /P> Hours to consider : 8 hours per day; Start : 8 pm End: 18 pm (24 hours format ) Lunch break start: 12:00 pm Lunc
$initialDate = '08/10/2015 09:30:24 am';
$finalDate = '15/10/2015 15:47:38 pm';
$holiday = '12/10/2015';
我必须考虑一下这些日子的时间。<强> < /P>
Hours to consider : 8 hours per day;
Start : 8 pm
End: 18 pm (24 hours format )
Lunch break start: 12:00 pm
Lunch break end: 14:00 pm
Example 1 : From 08/10/2015 10:00:00 to 09/10/2015 17:00:00 results 13 working hours. ( excludes lunch break )
Example 2 : From 08/10/2015 14:00:00 to 09/10/2015 18:00:00 results 12 working hours. ( Do not exclude 2 hours from begin date, because starts after 14:00 pm, lunch break )
Example 3 : From 08/10/2015 16:00:00 to 09/10/2015 18:00:00 results 10 working hours. ( Do not exclude 2 hours from begin date, because starts after 14:00 pmm lunch break )
Exampld 4 : From 08/10/2015 08:00:00 to 09/10/2015 11:00:00 results 14 working hours. ( Exclude 2 hours from begin date, and do not exclude 2 hours from end date, because isn't after 14:00 pm )
我必须计算这两个日期之间的工作时间和工作日,不包括周末和节假日,我怎么能做到?我正在使用PHP
我已经有些东西了,但是没有午餐休息。。。我在这里研究了StackOverFlow
代码:
function get_workdays($dataInicial,$dataFinal){
// arrays
$days_array = array();
$skipdays = array("Saturday", "Sunday");
$skipdates = get_feriados();
// other variables
$i = 0;
$current = $dataInicial;
if($current == $dataFinal) // same dates
{
$timestamp = strtotime($dataInicial);
if (!in_array(date("l", $timestamp), $skipdays)&&!in_array(date("Y-m-d", $timestamp), $skipdates)) {
$days_array[] = date("Y-m-d",$timestamp);
}
}
elseif($current < $dataFinal) // different dates
{
while ($current < $dataFinal) {
$timestamp = strtotime($dataInicial." +".$i." day");
if (!in_array(date("l", $timestamp), $skipdays)&&!in_array(date("Y-m-d", $timestamp), $skipdates)) {
$days_array[] = date("Y-m-d",$timestamp);
}
$current = date("Y-m-d",$timestamp);
$i++;
}
}
return $days_array;
}
function get_feriados(){
$dateAno = Date('Y');
$days_array = array(
$dateAno.'-10-12', // Padroeira do Brasil/ Dias das Crianças
$dateAno.'-11-02', // Finados
$dateAno.'-12-25' // Finados
);
return $days_array;
}
date_default_timezone_set('America/Sao_Paulo');
$dateAno = Date('Y');
$dataInicial = Date('08/10/2015 H:i');
$dataFinal = Date('13/10/2015 H:i');
// timestamps
$from_timestamp = strtotime(str_replace('/', '-', $dataInicial));
$to_timestamp = strtotime(str_replace('/', '-', $dataFinal));
// work day seconds
$workday_start_hour = 9;
$workday_end_hour = 17;
$workday_seconds = ($workday_end_hour - $workday_start_hour)*3600;
// work days beetwen dates, minus 1 day
$from_date = date('Y-m-d',$from_timestamp);
$to_date = date('Y-m-d',$to_timestamp);
$workdays_number = count(get_workdays($from_date,$to_date))-1;
$workdays_number = $workdays_number<0 ? 0 : $workdays_number;
// start and end time
$start_time_in_seconds = date("H",$from_timestamp)*3600+date("i",$from_timestamp)*60;
$end_time_in_seconds = date("H",$to_timestamp)*3600+date("i",$to_timestamp)*60;
// final calculations
$working_hours = ($workdays_number * $workday_seconds + $end_time_in_seconds - $start_time_in_seconds) / 86400 * 24;
print_r('<br/> Horas úteis '.$working_hours);
}
函数get_workdays($datainical,$dataFinal){
//阵列
$days_array=array();
$skipdays=数组(“星期六”、“星期日”);
$skipdates=get_feriados();
//其他变量
$i=0;
$current=$datainical;
如果($current==$dataFinal)//日期相同
{
$timestamp=strottime($datainical);
if(!in_数组(日期($l',$timestamp),$skipdays)和&!in_数组(日期($Y-m-d',$timestamp),$skipdates)){
$days_array[]=日期(“Y-m-d”,时间戳为$timestamp);
}
}
elseif($current<$dataFinal)//不同的日期
{
而($current<$dataFinal){
$timestamp=strottime($datainical.+“$i..”天);
if(!in_数组(日期($l',$timestamp),$skipdays)和&!in_数组(日期($Y-m-d',$timestamp),$skipdates)){
$days_array[]=日期(“Y-m-d”,时间戳为$timestamp);
}
$current=日期(“Y-m-d”,时间戳为$timestamp);
$i++;
}
}
返回$days\u数组;
}
函数get_feriados(){
$dateAno=日期('Y');
$days\u数组=数组(
$dateAno.'-10-12',//Padroeira do Brasil/Dias das Crianças
$dateAno.'-11-02',//Finados
$dateAno.'-12-25'//Finados
);
返回$days\u数组;
}
日期默认时区设置(“美国/圣保罗”);
$dateAno=日期('Y');
$DATAINICAL=日期('08/10/2015 H:i');
$dataFinal=日期('13/10/2015 H:i');
//时间戳
$from_timestamp=strtotime(str_replace('/','-',$datainical));
$to_timestamp=strtotime(str_replace('/','-',$dataFinal));
//工作日秒数
$workday\u start\u hour=9;
$workday\u end\u hour=17;
$workday_seconds=($workday_end_hour-$workday_start_hour)*3600;
//工作日减去日期,减去1天
$from_date=日期('Y-m-d',$from_时间戳);
$to_date=日期('Y-m-d',$to_时间戳);
$workdays\u number=计数(获取工作日($from\u date,$to\u date))-1;
$workdays\u number=$workdays\u number如果使用PHP5.3或更高版本,可以执行以下操作:
$datefrom = DateTime::createFromFormat('d/m/Y', '08/10/2015');
$dateto = DateTime::createFromFormat('d/m/Y', '15/10/2015');
$interval = $datefrom->diff($dateto);
$days = intval($interval->format('%a'));
如果满足以下条件,您还可以删除假日:
if ($datetime1->getTimestamp() < $holiday->getTimestamp() and $datetime2->getTimestamp() > $holiday->getTimestamp()) $days--;
你可以计算发射时间的总和,然后减去它。
如何忽略周末或计算忽略天数:
while($dateto->getTimestamp() > $datefrom->getTimestamp()) {
if (in_array($datefrom->format('w'), array('0','6'))) $ignore_days += 1;
$datefrom->modify('+1 day');
}
如果使用PHP 5.3或更高版本,可以执行以下操作:
$datefrom = DateTime::createFromFormat('d/m/Y', '08/10/2015');
$dateto = DateTime::createFromFormat('d/m/Y', '15/10/2015');
$interval = $datefrom->diff($dateto);
$days = intval($interval->format('%a'));
如果满足以下条件,您还可以删除假日:
if ($datetime1->getTimestamp() < $holiday->getTimestamp() and $datetime2->getTimestamp() > $holiday->getTimestamp()) $days--;
你可以计算发射时间的总和,然后减去它。
如何忽略周末或计算忽略天数:
while($dateto->getTimestamp() > $datefrom->getTimestamp()) {
if (in_array($datefrom->format('w'), array('0','6'))) $ignore_days += 1;
$datefrom->modify('+1 day');
}
检查下面的代码,该代码将返回工作天数
function number_of_working_days($from, $to) {
$workingDays = [1, 2, 3, 4, 5];// date format = (1 = Monday,2 = Tue, ...)
$holidayDays = ['*-12-25', '*-02-14', '2015-12-23']; // variable and fixed holidays
$from = new DateTime($from);
$to = new DateTime($to);
$to->modify('+1 day');
$interval = new DateInterval('P1D');
$days = new DatePeriod($from, $interval, $to);
$no_of_working_days = 0;
foreach ($days as $day) {
if (!in_array($day->format('N'), $workingDays)||in_array($day->format('Y-m-d'), $holidayDays)||in_array($day->format('*-m-d'), $holidayDays)) {continue;}
$working_days++;
}
return $no_of_working_days;
}
echo number_of_working_days('2015-12-01', '2015-09-10');
从中可以轻松计算工作小时数。检查下面的代码,该代码将返回工作天数
function number_of_working_days($from, $to) {
$workingDays = [1, 2, 3, 4, 5];// date format = (1 = Monday,2 = Tue, ...)
$holidayDays = ['*-12-25', '*-02-14', '2015-12-23']; // variable and fixed holidays
$from = new DateTime($from);
$to = new DateTime($to);
$to->modify('+1 day');
$interval = new DateInterval('P1D');
$days = new DatePeriod($from, $interval, $to);
$no_of_working_days = 0;
foreach ($days as $day) {
if (!in_array($day->format('N'), $workingDays)||in_array($day->format('Y-m-d'), $holidayDays)||in_array($day->format('*-m-d'), $holidayDays)) {continue;}
$working_days++;
}
return $no_of_working_days;
}
echo number_of_working_days('2015-12-01', '2015-09-10');
你可以很容易地计算出工作时间。我为你创建了一个很好的类,你可以使用它。它需要
nesbot/carbon
库(),您可以这样使用它:
$calc = new HoursCalculator(
Carbon::createFromFormat("Y-m-d H:i", "2015-10-7 09:00"),
Carbon::createFromFormat("Y-m-d H:i", "2015-10-14 18:00"),
[
"2015-10-13"
]
);
echo $calc->getHours();
这是课程:
class HoursCalculator {
const LUNCH_HOURS = 2;
protected $start;
protected $end;
protected $holidays;
protected $hoursTotal;
public function __construct(Carbon $start, Carbon $end, $holidays = [])
{
$this->start = $start;
$this->end = $end;
$this->holidays = $holidays;
}
public function getHours()
{
$dayHours = $this->getHoursInADay();
return $this->calculateHours($dayHours);
}
protected function getHoursInADay()
{
$start = $this->start;
$end = Carbon::createFromFormat("Y-m-d H:i", $this->start->format("Y-m-d") . " " . $this->end->format("H:i"));
return $start->diffInHours($end) - self::LUNCH_HOURS;
}
protected function getStartDate()
{
return $this->start->format('Y-m-d');
}
protected function calculateHours($hoursInDay)
{
$start = $this->start->copy()->startOfDay();
$end = $this->end->copy()->endOfDay();
$days = 0;
while($start->lt($end)) {
if (!$this->isHoliday($start) && !$this->isWeekend($start)) {
$days++;
}
$start->addDay(1);
}
return $days * $hoursInDay;
}
protected function isHoliday(Carbon $date)
{
$date->startOfDay();
foreach($this->holidays as $holiday) {
$holiday = Carbon::createFromFormat("Y-m-d", $holiday)->startOfDay();
if ($date->eq($holiday)) {
return true;
}
}
return false;
}
protected function isWeekend(Carbon $date)
{
return $date->isWeekend();
}
}
希望这有帮助 我为您创建了一个很好的类,您可以使用它。它需要
nesbot/carbon
库(),您可以这样使用它:
$calc = new HoursCalculator(
Carbon::createFromFormat("Y-m-d H:i", "2015-10-7 09:00"),
Carbon::createFromFormat("Y-m-d H:i", "2015-10-14 18:00"),
[
"2015-10-13"
]
);
echo $calc->getHours();
这是课程:
class HoursCalculator {
const LUNCH_HOURS = 2;
protected $start;
protected $end;
protected $holidays;
protected $hoursTotal;
public function __construct(Carbon $start, Carbon $end, $holidays = [])
{
$this->start = $start;
$this->end = $end;
$this->holidays = $holidays;
}
public function getHours()
{
$dayHours = $this->getHoursInADay();
return $this->calculateHours($dayHours);
}
protected function getHoursInADay()
{
$start = $this->start;
$end = Carbon::createFromFormat("Y-m-d H:i", $this->start->format("Y-m-d") . " " . $this->end->format("H:i"));
return $start->diffInHours($end) - self::LUNCH_HOURS;
}
protected function getStartDate()
{
return $this->start->format('Y-m-d');
}
protected function calculateHours($hoursInDay)
{
$start = $this->start->copy()->startOfDay();
$end = $this->end->copy()->endOfDay();
$days = 0;
while($start->lt($end)) {
if (!$this->isHoliday($start) && !$this->isWeekend($start)) {
$days++;
}
$start->addDay(1);
}
return $days * $hoursInDay;
}
protected function isHoliday(Carbon $date)
{
$date->startOfDay();
foreach($this->holidays as $holiday) {
$holiday = Carbon::createFromFormat("Y-m-d", $holiday)->startOfDay();
if ($date->eq($holiday)) {
return true;
}
}
return false;
}
protected function isWeekend(Carbon $date)
{
return $date->isWeekend();
}
}
希望这有帮助 我想这会满足你的要求。但是我改变了日期时间格式如下。检查一下。使用较少的评论。如果有任何疑问,请询问。假日是数组,可根据需要添加和删除 处理12:00到14:00之间的时间。 处理08:00以下的时间。 处理18:00以上的时间
<?php
$initialDate = '2015-10-13 08:15:00'; //start date and time in YMD format
$finalDate = '2015-10-14 11:00:00'; //end date and time in YMD format
$holiday = array('2015-10-12'); //holidays as array
$noofholiday = sizeof($holiday); //no of total holidays
//create all required date time objects
$firstdate = DateTime::createFromFormat('Y-m-d H:i:s',$initialDate);
$lastdate = DateTime::createFromFormat('Y-m-d H:i:s',$finalDate);
if($lastdate > $firstdate)
{
$first = $firstdate->format('Y-m-d');
$first = DateTime::createFromFormat('Y-m-d H:i:s',$first." 00:00:00" );
$last = $lastdate->format('Y-m-d');
$last = DateTime::createFromFormat('Y-m-d H:i:s',$last." 23:59:59" );
$workhours = 0; //working hours
for ($i = $first;$i<=$last;$i->modify('+1 day') )
{
$holiday = false;
for($k=0;$k<$noofholiday;$k++) //excluding holidays
{
if($i == $holiday[$k])
{
$holiday = true;
break;
} }
$day = $i->format('l');
if($day === 'Saturday' || $day === 'Sunday') //excluding saturday, sunday
$holiday = true;
if(!$holiday)
{
$ii = $i ->format('Y-m-d');
$f = $firstdate->format('Y-m-d');
$l = $lastdate->format('Y-m-d');
if($l ==$f )
$workhours +=sameday($firstdate,$lastdate);
else if( $ii===$f)
$workhours +=firstday($firstdate);
else if ($l ===$ii)
$workhours +=lastday($lastdate);
else
$workhours +=8;
}
}
echo $workhours; //echo the hours
}
else
echo "lastdate less than first date";
function sameday($firstdate,$lastdate)
{
$fmin = $firstdate->format('i');
$fhour = $firstdate->format('H');
$lmin = $lastdate->format('i');
$lhour = $lastdate->format('H');
if($fhour >=12 && $fhour <14)
$fhour = 14;
if($fhour <8)
$fhour =8;
if($fhour >=18)
$fhour =18;
if($lhour<8)
$lhour=8;
if($lhour>=12 && $lhour<14)
$lhour = 14;
if($lhour>=18)
$lhour = 18;
if($lmin == 0)
$min = ((60-$fmin)/60)-1;
else
$min = ($lmin-$fmin)/60;
return $lhour-$fhour + $min;
}
function firstday($firstdate) //calculation of hours of first day
{
$stmin = $firstdate->format('i');
$sthour = $firstdate->format('H');
if($sthour<8) //time before morning 8
$lochour = 8;
else if($sthour>18)
$lochour = 0;
else if($sthour >=12 && $sthour<14)
$lochour = 4;
else
{
$lochour = 18-$sthour;
if($sthour<=14)
$lochour-=2;
if($stmin == 0)
$locmin =0;
else
$locmin = 1-( (60-$stmin)/60); //in hours
$lochour -= $locmin;
}
return $lochour;
}
function lastday($lastdate) //calculation of hours of last day
{
$stmin = $lastdate->format('i');
$sthour = $lastdate->format('H');
if($sthour>=18) //time after 18
$lochour = 8;
else if($sthour<8) //time before morning 8
$lochour = 0;
else if($sthour >=12 && $sthour<14)
$lochour = 4;
else
{
$lochour = $sthour - 8;
$locmin = $stmin/60; //in hours
if($sthour>14)
$lochour-=2;
$lochour += $locmin;
}
return $lochour;
}
?>
我希望这能满足您的所有需求。但是我改变了日期时间格式如下。检查一下。使用较少的评论。如果有任何疑问,请询问。假日是数组,可根据需要添加和删除 处理12:00到14:00之间的时间。 处理08:00以下的时间。 处理18:00以上的时间
<?php
$initialDate = '2015-10-13 08:15:00'; //start date and time in YMD format
$finalDate = '2015-10-14 11:00:00'; //end date and time in YMD format
$holiday = array('2015-10-12'); //holidays as array
$noofholiday = sizeof($holiday); //no of total holidays
//create all required date time objects
$firstdate = DateTime::createFromFormat('Y-m-d H:i:s',$initialDate);
$lastdate = DateTime::createFromFormat('Y-m-d H:i:s',$finalDate);
if($lastdate > $firstdate)
{
$first = $firstdate->format('Y-m-d');
$first = DateTime::createFromFormat('Y-m-d H:i:s',$first." 00:00:00" );
$last = $lastdate->format('Y-m-d');
$last = DateTime::createFromFormat('Y-m-d H:i:s',$last." 23:59:59" );
$workhours = 0; //working hours
for ($i = $first;$i<=$last;$i->modify('+1 day') )
{
$holiday = false;
for($k=0;$k<$noofholiday;$k++) //excluding holidays
{
if($i == $holiday[$k])
{
$holiday = true;
break;
} }
$day = $i->format('l');
if($day === 'Saturday' || $day === 'Sunday') //excluding saturday, sunday
$holiday = true;
if(!$holiday)
{
$ii = $i ->format('Y-m-d');
$f = $firstdate->format('Y-m-d');
$l = $lastdate->format('Y-m-d');
if($l ==$f )
$workhours +=sameday($firstdate,$lastdate);
else if( $ii===$f)
$workhours +=firstday($firstdate);
else if ($l ===$ii)
$workhours +=lastday($lastdate);
else
$workhours +=8;
}
}
echo $workhours; //echo the hours
}
else
echo "lastdate less than first date";
function sameday($firstdate,$lastdate)
{
$fmin = $firstdate->format('i');
$fhour = $firstdate->format('H');
$lmin = $lastdate->format('i');
$lhour = $lastdate->format('H');
if($fhour >=12 && $fhour <14)
$fhour = 14;
if($fhour <8)
$fhour =8;
if($fhour >=18)
$fhour =18;
if($lhour<8)
$lhour=8;
if($lhour>=12 && $lhour<14)
$lhour = 14;
if($lhour>=18)
$lhour = 18;
if($lmin == 0)
$min = ((60-$fmin)/60)-1;
else
$min = ($lmin-$fmin)/60;
return $lhour-$fhour + $min;
}
function firstday($firstdate) //calculation of hours of first day
{
$stmin = $firstdate->format('i');
$sthour = $firstdate->format('H');
if($sthour<8) //time before morning 8
$lochour = 8;
else if($sthour>18)
$lochour = 0;
else if($sthour >=12 && $sthour<14)
$lochour = 4;
else
{
$lochour = 18-$sthour;
if($sthour<=14)
$lochour-=2;
if($stmin == 0)
$locmin =0;
else
$locmin = 1-( (60-$stmin)/60); //in hours
$lochour -= $locmin;
}
return $lochour;
}
function lastday($lastdate) //calculation of hours of last day
{
$stmin = $lastdate->format('i');
$sthour = $lastdate->format('H');
if($sthour>=18) //time after 18
$lochour = 8;
else if($sthour<8) //time before morning 8
$lochour = 0;
else if($sthour >=12 && $sthour<14)
$lochour = 4;
else
{
$lochour = $sthour - 8;
$locmin = $stmin/60; //in hours
if($sthour>14)
$lochour-=2;
$lochour += $locmin;
}
return $lochour;
}
?>
首先,谢谢你的帮助……但是我必须考虑开始时间和结束时间,不包括午休时间(2小时)。工作时间=$workingDays*8$午餐休息时间=$workingDays*2$totalTimeSpent=$workingHours-$午餐休息时间;我怎么考虑这些日子的时间呢?如下:$initialDate='08/10/2015 09:30:24 am'$最终日期='2015年10月15日下午15:47:38';首先,谢谢你的帮助……但是我必须考虑开始时间和结束时间,不包括午休时间(2小时)。工作时间=$workingDays*8$午餐休息时间=$workingDays*2$totalTimeSpent=$workingHours-$午餐休息时间;我怎么考虑这些日子的时间呢?如下:$initialDate='08/10/2015 09:30:24 am'$最终日期='2015年10月15日下午15:47:38';首先,谢谢你的帮助……但是我必须考虑开始时间和结束时间。示例:$workday\u start\u hour=9;$break\u午餐\u start=12;$break\u午餐\u end=14;$workday\u end\u hour=19`我完全不明白你有什么数据。。。你想计算什么数据。我编辑了我的文章,我想考虑工作时间,像上面一样,上午9点开始,晚上结束。你看到有小时的约会了吗?非常感谢。但是我怎么能每天只考虑8个小时的工作呢?上午8:00开始,下午18:00结束。我正在测试你的代码并试图理解。谢谢你的帮助。首先,谢谢你的帮助……但我必须考虑开始时间和结束时间的日子。示例:$workday\u start\u hour=9;$break\u午餐\u start=12;$break\u午餐\u end=14;$workday\u end\u hour=19`我完全不明白你有什么数据。。。你想计算什么数据。我编辑了我的文章,我想考虑工作时间,像上面一样,上午9点开始,晚上结束。你看到有小时的约会了吗?非常感谢。但是我怎么能每天只考虑8个小时的工作呢?上午8:00开始,下午18:00结束。我正在测试你的代码并试图理解。谢谢你的帮助