Несмотря на ответ уже предусмотрено, вот небольшой отрывок с классом обработки все для вас:
<?php
class dateRange {
protected $start, $end, $daysToExclude, $datesToExclude;
function __construct($dateStart, $dateEnd, $daysToExclude, $datesToExclude) {
$this->start = $dateStart;
$this->end = $dateEnd;
$this->daysToExclude = $daysToExclude;
$this->datesToExclude = $this->fixFormat($datesToExclude);
}
public function getRangeLength ($callback = null) {
$tmp = array();
$now = strtotime($this->start);
$to = strtotime($this->end);
while ($now <= $to) {
if (!in_array(date("w", $now), $this->daysToExclude)) {
$tmp[] = date('d-m-Y', $now);
}
$now = strtotime('+1 day', $now);
}
is_callable($callback) && call_user_func($callback, array_diff($tmp,$this->datesToExclude));
return count(array_diff($tmp,$this->datesToExclude));
}
private function fixFormat($el) {
if (!is_array($el)) {
return false;
}
else {
foreach ($el as &$value) {
$value = date("d-m-Y",strtotime($value));
}
return $el;
}
}
}
?>
я решил сохранить текущую логику (используя date_diff), но я подумал, что, в в будущем у вас может быть ваш босс, говорящий вам: «Знаете, что? Я не хочу иметь понедельники, а там», поэтому в текущей системе вам придется вручную редактировать свою функцию и, возможно, вы не будете помнить больше того, что вы сделали.
Класс выше ожидает, что четыре параметра:
- dateStart (ДМГ формат)
- dateEnd (ДМГ формат)
- daysToExclude (массив с идентификаторами дней, чтобы исключить -> например, массив (0, 6) исключить субботу и воскресенье).
- dateToExclude (массив с датами для исключения, каждый поддерживаемый формат).
Класс автоматически исправит датыВыберите формат массива, чтобы вы могли использовать date_diff.
Ниже приведен пример, чтобы использовать его, следуя вашему делу:
<?php
$dateStart = "01-05-2015";
$dateEnd = "01-06-2015";
$daysToExclude = array(0,6);
$exclusions = array(
"1-05-2015",
"2-05-2015",
"4-05-2015",
"5-05-2015",
"7-05-2015",
"8-05-2015",
"9-05-2015",
"11-05-2015",
"12-05-2015",
"14-05-2015",
"15-05-2015",
"16-05-2015",
"18-05-2015",
"19-05-2015",
"21-05-2015",
"22-05-2015",
"23-05-2015",
"25-05-2015",
"26-05-2015",
"28-05-2015",
"29-05-2015",
"30-05-2015"
);
$dateRange = new dateRange($dateStart, $dateEnd, $daysToExclude, $exclusions);
echo $dateRange->getRangeLength();
?>
Код выше выходов 5.
Функция getRangeLength также принимает обратный вызов и возвращает array
в результате операции date_diff , так что вы можете также:
$dateRange->getRangeLength(function($res) {
echo "Literal output: <br />";
print_r($res);
echo "<br />count is: " . count($res);
});
Приведенные выше результаты:
Literal output:
Array ([3] => 06-05-2015 [8] => 13-05-2015 [13] => 20-05-2015 [18] => 27-05-2015 [21] => 01-06-2015)
count is: 5
Так что, если вы впоследствии нужны будете удалить понедельники тоже, вы сможете легко сделать это путем изменения daysToExclude к array(0,1,6);
Надеются, что это будет полезно для всех, кто будет нуждаться в этом, несмотря на действительный ответ уже опубликован.
Ваша оригинальная проблема, в любом случае, была в значительной степени связана с функцией array_diff
, которая НЕ выполняла свою работу из-за того, что строки даты были несовместимы, поскольку «1-01-2015» отличается от «01-01-2015», если вы сначала не конвертируете их по времени, а затем обратно в даты.
Здесь есть несколько проблем. Прежде всего, я начну с вопроса: почему вы устанавливаете $ date [0]? Тем не менее, array_diff не будет работать, потому что $ hsdarray date «1-05-2015» отличается от «01-05-2015», поэтому ваша разница не будет работать. Другая проблема: потому что вы исключаете воскресенья (и, возможно, субботы, но я не вижу этого в вашем коде), array_diff выведет AT LEAST: 16-05-2015 (суббота), 23-05-2015 (суббота) и 30-05-2015 (суббота). – briosheje