我如何构建条件,仅在上午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;
但是我会为完成上述工作添加什么?
答案 0 :(得分:1)
使用“魔术数字”并使用日期进行大量数学操作会降低您的代码的可读性,并且还会导致问题 - 它不能很好地处理成年,夏令时,时区或所有其他奇怪的问题附带日期和时间。
如果可能,你应该总是使用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 class可以更好地实现它,但这是相当新的,我对它不熟悉,所以我坚持使用strtotime()。
答案 1 :(得分:0)
日期函数与UNIX时间戳一起使用,因此我只添加86400(一天中的秒数),然后将其除以24并乘以2.这恰好是2小时。
$time1 = date('Y-m-d G:i', strtotime($idate1)+86400/12);
如果您只想在一段时间内应用这些更改,可以使用(timestamp modulo 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时区才能实现此目的。