Как бы я структурировал условия, чтобы добавить два часа только к датам между 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('Ymd G:i', strtotime('+120 minutes', $idate1)); $_POST['due_date'] = $time1;
Я пробовал эту функцию, и она отлично работает, за исключением случаев, когда я использую дату (2013-11-26 12:30), которую он дает мне (2013-11-27 04:30:00), проблема заключается в 12:30
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 5.3 или выше
<?php function addRollover($givenDate, $addtime) { $datetime = new DateTime($givenDate); $datetime->modify($addtime); if (in_array($datetime->format('l'), array('Sunday','Saturday')) || 17 < $datetime->format('G') || (17 === $datetime->format('G') && 30 < $datetime->format('G')) ) { $endofday = clone $datetime; $endofday->setTime(17,30); $interval = $datetime->diff($endofday); $datetime->add(new DateInterval('P1D')); if (in_array($datetime->format('l'), array('Saturday', 'Sunday'))) { $datetime->modify('next Monday'); } $datetime->setTime(8,30); $datetime->add($interval); } return $datetime; } $future = addRollover('2014-01-03 15:15:00', '+4 hours'); echo $future->format('Ymd H:i:s');
Смотрите это в действии
Вот объяснение того, что происходит:
Сначала мы создаем объект DateTime, представляющий нашу начальную дату / время
Затем мы добавляем к нему определенное количество времени (см. Поддерживаемые форматы даты и времени )
Мы проверяем, есть ли уик-энд после 6 вечера или в 5 часов вечера с более чем 30 минутами (например, после 17:30)
Если это так, мы клонируем наш объект datetime и устанавливаем его в 17:30
Затем мы получаем разницу между временем окончания (5:30 PM) и измененным временем как объект DateInterval
Затем мы переходим к следующему дню
Если на следующий день в субботу мы переходим к следующему дню
Если на следующий день будет воскресенье, мы перейдем к следующему дню
Затем мы установили время до 8:30 утра
Затем мы добавляем нашу разницу между временем окончания (5:30 PM) и измененным временем до нашего объекта datetime
Мы возвращаем объект из функции