问题描述
我想计算两个日期之间的工作时间。所以我需要星期六/星期几被忽视,我的工作时间是从上午9点到下午6点(9点到18点)。
I want to calculate the working hours between two dates. So I need saturday/sunday to be ignored and my working time is from 9am to 6pm (9:00 to 18:00).
我搜索网页和尝试了一些变化,但似乎没有任何工作。任何人都可以帮助?
I'v search the web and tried some variations, but nothing seems to be working. Any one can help?
我一直在看这个链接:
http://stackoverflow.com/questions/12374275/subtract-non-working-hours-and-days -from-two-given-times-in-php
I'v been looking at this links:Calculating working hours between two dateshttp://stackoverflow.com/questions/12374275/subtract-non-working-hours-and-days-from-two-given-times-in-phpcalc the working hours between 2 dates in PHP
但是,或者他们没有得到答案或提供的答案不起作用。
But or they didn't get the answer or the answer provided its not working.
感谢任何帮助
推荐答案
我在网上调整了一些功能, stackoverflow我的需要。这里是。
I adapted some functions on web and here on stackoverflow to my needs. Here they are.
调用脚本:
date_default_timezone_set("Europe/Lisbon");
$startDate=strtotime('2012-11-30 00:15:33');
$endDate = strtotime('2012-12-05 10:15:00');
echo "Working hours from create date until due date -> ".seconds2human(work_hours_diff($startDate,$endDate));
人们可以读取秒数(从):
Place seconds readable by humans (adapted from http://snippetsofcode.wordpress.com/2012/08/25/php-function-to-convert-seconds-into-human-readable-format-months-days-hours-minutes/):
function seconds2human($ss) {
$s = $ss%60;
$m = floor(($ss%3600)/60);
$h = floor(($ss)/3600);
return "$h hours, $m minutes, $s seconds";
}
使用工作日和工作时间的子跟踪日期(从):
Subtrack dates using business days and working hours (adapted from Calculating working hours between two dates):
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(9, 17.5); // from 9:00 to 17:30 (8.5 hours)
$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;
//In case date1 is on same day of date2
if (mktime(0,0,0,date('n', $date1), date('j', $date1), date('Y', $date1))==mktime(0,0,0,date('n', $date2), date('j', $date2), date('Y', $date2))) {
//If its not working day, then return 0
if (!in_array(date('w', $date1), $working_days)) return 0;
$date0 = mktime($beg_h, $beg_m, 0, date('n', $date1), date('j', $date1), date('Y', $date1));
$date3 = mktime($end_h, $end_m, 0, date('n', $date1), date('j', $date1), date('Y', $date1));
if ($date1<$date0) {
if ($date2<$date0) return 0;
$date1 = $date0;
if ($date2>$date3) $date2=$date3;
return $date2-$date1;
}
if ($date1>$date3) return 0;
if ($date2>$date3) $date2=$date3;
return $date2-$date1;
}
//setup the very next first working time stamp
if (!in_array(date('w',$current_date) , $working_days)) {
// the current day is not a working day
// the current time stamp is set at the beginning 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, 0, 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 beginning 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, 0, date('n',$current_date), date('j',$current_date), date('Y',$current_date) );
$seconds = $date0-$current_date;
// 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 ) {
if (in_array(date('w',$current_date) , $working_days) ) $days++; // it's a working day
$current_date += 24*3600; // next day
}
$days--; //because we've already count the first day (in $seconds)
// check if end's timestamp is inside working hours
$date0 = mktime( $beg_h, $beg_m, 0, date('n',$date2), date('j',$date2), date('Y',$date2) );
if ((!in_array(date('w', $date2), $working_days)) || ($date2 < $date0)) {
// it's before, so nothing more !
} else {
// is it after ?
$date3 = mktime( $end_h, $end_m, 0, 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;
$seconds += $tmp;
}
// calculate the working days in seconds
$seconds += 3600*($working_hours[1]-$working_hours[0])*$days;
return $sign * $seconds;
}
这篇关于PHP - 减去工作日和工作时间的日期的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!