我想计算两个日期之间的工作时间。我使用的是working_hours_diff函数,这里有答案;https://stackoverflow.com/a/8927347/4671728
实际上,它是正常计算的,但当我输入两个相同的日期但不同的小时时,它会返回错误的值。例如29-12-2015 13:17:43和29-12-2015 11:17:39-返回11小时,但应返回2小时。然而,当我输入彼此不同的日期时,它会正确计算。
您可以在下面找到代码;
function work_hours_diff($date1,$date2) {
if ($date1>$date2) { $tmp=$date1; $date1=$date2; $date2=$tmp; unset($tmp); $sign=-1; } else $sign = 1;
if ($date1==$date2) return 0;
$days = 0;
$working_days = array(1,2,3,4,5); // Monday-->Friday
$working_hours = array(8, 17); // from 8:30(am) to 17:30
$current_date = $date1;
$beg_h = floor($working_hours[0]); $beg_m = ($working_hours[0]*60)%60;
$end_h = floor($working_hours[1]); $end_m = ($working_hours[1]*60)%60;
// setup the very next first working timestamp
if (!in_array(date('w',$current_date) , $working_days)) {
// the current day is not a working day
// the current timestamp is set at the begining of the working day
$current_date = mktime( $beg_h, $beg_m, 0, date('n',$current_date), date('j',$current_date), date('Y',$current_date) );
// search for the next working day
while ( !in_array(date('w',$current_date) , $working_days) ) {
$current_date += 24*3600; // next day
}
} else {
// check if the current timestamp is inside working hours
$date0 = mktime( $beg_h, $beg_m, 0, date('n',$current_date), date('j',$current_date), date('Y',$current_date) );
// it's before working hours, let's update it
if ($current_date<$date0) $current_date = $date0;
$date3 = mktime( $end_h, $end_m, 59, date('n',$current_date), date('j',$current_date), date('Y',$current_date) );
if ($date3<$current_date) {
// outch ! it's after working hours, let's find the next working day
$current_date += 24*3600; // the day after
// and set timestamp as the begining of the working day
$current_date = mktime( $beg_h, $beg_m, 0, date('n',$current_date), date('j',$current_date), date('Y',$current_date) );
while ( !in_array(date('w',$current_date) , $working_days) ) {
$current_date += 24*3600; // next day
}
}
}
// so, $current_date is now the first working timestamp available...
// calculate the number of seconds from current timestamp to the end of the working day
$date0 = mktime( $end_h, $end_m, 59, date('n',$current_date), date('j',$current_date), date('Y',$current_date) );
$seconds = $date0-$current_date+1;
//printf("<br>From %s To %s : %d hours<br>",date('d/m/y H:i',$date1),date('d/m/y H:i',$date0),$seconds/3600);
// calculate the number of days from the current day to the end day
$date3 = mktime( $beg_h, $beg_m, 0, date('n',$date2), date('j',$date2), date('Y',$date2) );
while ( $current_date < $date3 ) {
$current_date += 24*3600; // next day
if (in_array(date('w',$current_date) , $working_days) ) $days++; // it's a working day
}
if ($days>0) $days--; //because we've allready count the first day (in $seconds)
//printf("<br>From %s To %s : %d working days<br>",date('d/m/y H:i',$date1),date('d/m/y H:i',$date3),$days);
// check if end's timestamp is inside working hours
$date0 = mktime( $beg_h, 0, 0, date('n',$date2), date('j',$date2), date('Y',$date2) );
if ($date2<$date0) {
// it's before, so nothing more !
} else {
// is it after ?
$date3 = mktime( $end_h, $end_m, 59, date('n',$date2), date('j',$date2), date('Y',$date2) );
if ($date2>$date3) $date2=$date3;
// calculate the number of seconds from current timestamp to the final timestamp
$tmp = $date2-$date0+1;
$seconds += $tmp;
//printf("<br>From %s To %s : %d hours<br>",date('d/m/y H:i',$date2),date('d/m/y H:i',$date3),$tmp/3600);
}
// calculate the working days in seconds
$seconds += 3600*($working_hours[1]-$working_hours[0])*$days;
//printf("<br>From %s To %s : %d hours<br>",date('d/m/y H:i',$date1),date('d/m/y H:i',$date2),$seconds/3600);
//return $sign * $seconds/3600; // to get hours
return round($seconds/3600);
}
date_default_timezone_set("Europe/Istanbul");
$dt2 = strtotime("29-12-2015 11:17:39");
$dt1 = strtotime("29-12-2015 13:17:43");
echo work_hours_diff($dt1 , $dt2 );
替换此行:
if ($days>0) $days--; //because we've allready count the first day (in $seconds)
带有:
$days--; // because we've already counted the first day (in $seconds)
if
很糟糕,因为它消除了$days值0和1(在if
之前)之间的区别,这不可能是正确的。
试试这个。。
date_default_timezone_set("Europe/Istanbul");
$dt2 = strtotime("29-12-2015 11:17:39");
$dt1 = strtotime("29-12-2015 13:17:43");
echo $diff_hours = ($dt1 - $dt2)/3600;
输出
2.0011111111111 hours
更换
if ($days>0) $days--; //because we've allready count the first day (in $seconds)
为此:
if (in_array(date('w',$date2) , $working_days)) {
$days--; //because we've allready count the first day (in $seconds)
}