【发布时间】:2010-01-19 07:34:58
【问题描述】:
给定 2 个日期,我如何计算它们之间的小时/分钟数,不包括周末时间(从星期五 17:30 到星期一 09:00)
脚本查询 MySql 数据库,但我认为这种计算在 php 中会更容易。 我正在考虑一个迭代函数来确定工作日并一直循环到最后一个日期会小于当前日期指示器?
有什么建议吗?
【问题讨论】:
给定 2 个日期,我如何计算它们之间的小时/分钟数,不包括周末时间(从星期五 17:30 到星期一 09:00)
脚本查询 MySql 数据库,但我认为这种计算在 php 中会更容易。 我正在考虑一个迭代函数来确定工作日并一直循环到最后一个日期会小于当前日期指示器?
有什么建议吗?
【问题讨论】:
假设您有两个时间戳:$timestamp1 和 $timestamp2,您可以将它们减去并减去周末数:$difference - ($weekends*2*24*3600)。
function difWeekends($timestamp1, $timestamp2){
$difference = $timestamp2 - $timestamp1;
$nextWeekend = strtotime('next Saturday', $timestamp1);
$weekends = 0;
$weekendFound = true;
while($weekendFound){
if($nextWeekend < $timestamp2){
$weekendFound = false;
} else {
$nextWeekend = strtotime('+7 days', $nextWeekend);
$weekends++;
}
}
$difference -= $weekends*48*60*60;
$hours = $difference % 3600; // Not sure about this, I assume you already got this...
$difference -= $hours*3600;
$minutes = $difference % 60;
return array('hours'=>$hours, 'minutes'=>$minutes);
}
需要修改:
function difWeekends($timestamp1, $timestamp2){
$difference = $timestamp2 - $timestamp1;
// Calculate the start of the first next weekend
$nextWeekendStart = strtotime('next Friday 17:30', $timestamp1);
// Calculate the end of the first next weekend
$nextWeekendEnd = strtotime('next Monday 9:00', $nextWeekendStart);
// This wil hold the number of weekend-seconds that needs to be subtracted
$weekendSubtract = 0;
$weekendFound = true;
while($weekendFound){
// If $timestamp2 ends before the next weekend, no weekend is found. [] = weekends, --- is time range
// --- [ ]
if($timestamp2 < $nextWeekendStart){
$weekendFound = false;
} else {
// ----[-- ]
if($timestamp2 < $nextWeekendEnd){
$weekendSubtract += $timestamp2-$nextWeekendStart;
$weekendFound = false; // Last weekend was found
} else {
// ---[----]---
$weekendSubtract += $nextWeekendEnd - $nextWeekendStart;
$nextWeekendStart += 7*24*60*60;
$nextWeekendEnd += 7*24*60*60;
}
}
}
$difference -= $weekendSubtract;
$hours = $difference % 3600; // Not sure about this, I assume you already got this...
$difference -= $hours*3600;
$minutes = $difference % 60;
return array('hours'=>$hours, 'minutes'=>$minutes);
}
【讨论】:
感谢 Harmen,您的代码为我指明了正确的方向。非常感谢!
当timestamp1在星期五时,您的解决方案没有考虑,=>而不是“下星期五”应该是“本星期五”
我进行了扩展,以便时间戳可以涵盖多个周末,而不仅仅是一个。
function timeDiffWeekendsOff($timestamp1, $timestamp2){
// Double check $timestamp2 is after and not before $timestamp1
if ($timestamp2 < $timestamp1) return 0;
// All-time difference
$difference = $timestamp2 - $timestamp1;
// This will hold the number of weekend-seconds that needs to be subtracted
$weekendSubtract = 0;
$keepLoop = true;
$currentDayStart = $timestamp1;
while ($keepLoop) {
if (isSameDay($currentDayStart,$timestamp2)){
$keepLoop = false; // exit at the last day
$currentDayEnd = $timestamp2;
} else {
$currentDayEnd = strtotime('tomorrow 00:00', $currentDayStart);
}
switch (date('w',$currentDayStart)){ // 0 - Sunday, 1 - Monday, 5 - Friday, 6 - Saturday
case 5: // Friday
$weekendSubtract += timeIntersect($currentDayStart, $currentDayEnd, strtotime('this Friday 17:30', $currentDayStart), strtotime('this Saturday 00:00', $currentDayStart));
break;
case 6: // full weekend days, 0 - Sunday, 6 - Saturday
case 0:
$weekendSubtract += $currentDayEnd - $currentDayStart;
break;
case 1: // Monday
$weekendSubtract += timeIntersect($currentDayStart, $currentDayEnd, strtotime('this Monday 00:00', $currentDayStart), strtotime('this Monday 09:00', $currentDayStart));
default:
break;
} // end switch
// -- lastly, set the new day start
$currentDayStart = strtotime('tomorrow 00:00', $currentDayStart);
} // end while $keepLoop
$difference -= $weekendSubtract;
return $difference;
}
function isSameDay($compare1, $compare2){
if (date('Ymd',$compare1)==date('Ymd',$compare2))
return true;
else
return false;
}
function timeIntersect($time1_from, $time1_to, $time2_from, $time2_to){
$overlap = min($time1_to, $time2_to) - max($time1_from, $time2_from);
if ($overlap < 0) $overlap = 0;
return $overlap;
}
【讨论】: