w35l3y, кажется, работает хорошо, поэтому я проголосовал за него. Тем не менее, я предпочел что-то более легкое, с меньшим количеством математики и циклов (хотя не уверен, что это важно с точки зрения производительности). Я думаю, что я рассмотрел все возможные сценарии ... Вот что я придумал:
function numDays($sday, $eday, $i, $cnt) {
if (($sday < $eday && $i >= $sday && $i <= $eday) || ($sday > $eday && ($i >= $sday || $i <= $eday))) {
// partial week (implied by $sday != $eday), so $i (day iteration) may have occurred one more time
// a) end day is ahead of start day; $i is within start/end of week range
// b) start day is ahead of end day (i.e., Tue start, Sun end); $i is either in back half of first week or front half of second week
$cnt++;
} elseif ($sday == $eday && $i == $sday) {
// start day and end day are the same, and $i is that day, i.e., Tue occurs twice from Tue-Tue (1 wk, so $wks = $cnt)
$cnt++;
}
return $cnt; // # of complete weeks + partial week, if applicable
}
Примечания: $ sday и $ eday - номера дней, соответствующие началу и концу проверяемого диапазона, а $ i - подсчитываемый номер дня (он у меня в цикле 0-6). Я переместил $ wks за пределы функции, так как бессмысленно каждый раз пересчитывать ее.
$wks = floor(($endstamp - $startstamp)/7*24*60*60);
$numDays = numDays($sday, $eday, $i, $wks);
Убедитесь, что начальные / конечные временные метки, которые вы сравниваете, имеют одинаковую настройку часового пояса, если таковая имеется, в противном случае вы всегда будете немного отключены с $ cnt и $ wks. (Я столкнулся с этим при подсчете от нескорректированного первого года до скорректированного дня / времени X.)