我如何构建条件,只在早上08:30到晚上18:30之间的日期上添加两个小时,不包括周六和周日?
如果给定了边界附近的时间(例如,周二17:30),则剩余时间应添加到下一个"有效"时间段的开始。
例如:如果给定的日期是星期二的17:30,那么两个小时的添加将导致星期三的9:30(17:30+1小时=18:30,8:30+剩余的1小时=9:30)。或者,如果给定的日期是周五17:00,结果将是周一9:00(周五17:00+1.5小时=18:30,周一8:30+剩余时间。5小时=9:00)
我知道如何简单地添加两个小时,如下所示:
$idate1 = strtotime($_POST['date']);
$time1 = date('Y-m-d G:i', strtotime('+120 minutes', $idate1));
$_POST['due_date'] = $time1;
但是,为了实现上述目标,我需要补充什么呢?
使用"幻数"并对日期进行大量计算会降低代码的可读性,也可能会导致问题——它无法很好地处理leapyears、夏令时、时区或日期和时间带来的所有其他奇怪之处。
如果可能,您应该始终使用strtotime()等辅助函数来处理日期,避免直接计算。
这是我做你想做的事情的方法,它并不完美(你不能加一个比两个时间段之间的间隔大的时间段,也就是说,从18:30到8:30的14个小时),它仍然使用了一些原始数学,但它是一个改进:
<?php
function addRollover($givenDate, $addtime) {
$starttime = 8.5*60; //Start time in minutes (decimal hours * 60)
$endtime = 18.5*60; //End time in minutes (decimal hours * 60)
$givenDate = strtotime($givenDate);
//Get just the day portion of the given time
$givenDay = strtotime('today', $givenDate);
//Calculate what the end of today's period is
$maxToday = strtotime("+$endtime minutes", $givenDay);
//Calculate the start of the next period
$nextPeriod = strtotime("tomorrow", $givenDay); //Set it to the next day
$nextPeriod = strtotime("+$starttime minutes", $nextPeriod); //And add the starting time
//If it's the weekend, bump it to Monday
if(date("D", $nextPeriod) == "Sat") {
$nextPeriod = strtotime("+2 days", $nextPeriod);
}
//Add the time period to the new day
$newDate = strtotime("+$addtime", $givenDate);
//print "$givenDate -> $newDate'n";
//print "$maxToday'n";
//Get the new hour as a decimal (adding minutes/60)
$hourfrac = date('H',$newDate) + date('i',$newDate)/60;
//print "$hourfrac'n";
//Check if we're outside the range needed
if($hourfrac < $starttime || $hourfrac > $endtime) {
//We're outside the range, find the remainder and add it on
$remainder = $newDate - $maxToday;
//print "$remainder'n";
$newDate = $nextPeriod + $remainder;
}
return $newDate;
}
?>
我已经注释掉了用于调试的打印语句,如果你想看看它是如何工作的,你可以取消注释它们(我建议!)你这样使用它:
<?php
print date('Y-m-d H:i:s',addRollover('2013-01-01 17:30','2 hours')) . "'n";
print date('Y-m-d H:i:s',addRollover('2013-01-01 18:00','3 hours')) . "'n";
print date('Y-m-d H:i:s',addRollover('2013-01-04 17:00','150 minutes')) . "'n";
?>
结果:
2013-01-02 09:30:00
2013-01-02 11:00:00
2013-01-07 09:30:00
这个代码应该可以很好地处理大多数奇怪的日期,比如时区、夏令时等等。使用PHP的DateTime类会更好地实现它,但这是一个相当新的类,我对它不太熟悉,所以我坚持使用strtotime()。
date函数使用UNIX时间戳,因此我只需将86400(一天中的秒数)相加,然后除以24,再乘以2。整整多了2个小时。
$time1 = date('Y-m-d G:i', strtotime($idate1)+86400/12);
如果您只想在特定的时间段内应用这些更改,您可以使用(时间戳模86400)公式来获得小时和分钟。
if(($idate%86400)>=(86400/24*8.5)&&($idate%86400)<=(86400/24*18.5))
$time1 = date('Y-m-d G:i', strtotime($idate1)+86400/12);
对于过滤周末,date()
将帮助您:
if(date("D",$idate)=="Sun" || date("D",$idate)=="Sat)
现在合并条件,我们得到第一部分的解决方案:
if(date("D",$idate)!="Sun" && date("D",$idate)!="Sat" && ($idate%86400)>=(86400/24*8.5)&&($idate%86400)<=(86400/24*18.5))
$time1 = date('Y-m-d G:i', strtotime($idate1)+86400/12);
注意:必须在脚本中使用UTC+0时区才能正常工作