как получить ДЕНЬ, отсутствующую в рабочие дни с данного диапазона дат?

Это была функция, которую я сделал для получения списка листингов, которые сотрудник взял за определенный диапазон дат. Это нормально, если взятые листья – один или два, но слишком сложный, так что требуется много времени для получения результатов, следовательно, ошибка таймаута! Любая помощь?

Это функция:

function dates_between($emp_id, $start_date, $end_date) { $day_incrementer = 1; $count_leaves = 0; $flag = 0; // Getting the days from DB where the employee '28' had worked in given date range $work_res = mysql_query("SELECT DISTINCT date FROM `work_details` WHERE employee_id='28' and date between '2012-02-01' and '2012-02-29'"); do { while($row = mysql_fetch_array($work_res)) { while((date("Ymd",$start_date) < $row['date']) && ($flag = 0)) // loop to find startdate less than table date! if table date(attendance) is starting from 3, we need to print leaves 1,2 if they are not weekends { if(!(date('N', strtotime(date("Ymd", $start_date))) >=6)) { //checking for weekends, prints only weekdays echo date("Ymd", $start_date) . " \n "; $count_leaves++; } $start_date = $start_date + ($day_incrementer * 60 * 60 *24); } $flag=1; while((date("Ymd",$start_date) != $row['date'])) // loop to print $start_date,which is not equal to table date { if(!(date('N', strtotime(date("Ymd", $start_date))) >= 6)) { echo date("Ymd", $start_date) . "\n"; $count_leaves++; } $$start_date = $start_date + ($day_incrementer * 60 * 60 * 24); } $start_date = $start_date + ($day_incrementer * 60 * 60 * 24); } // loop to print $start_date,comes rest after tabledate if tabledate finishes with 28, prints rest of dates 29,30 if(!(date('N', strtotime(date("Ymd", $start_date))) >= 6) && ($start_date <= $end_date)) { echo date("Ymd", $start_date) . "\n"; $count_leaves++; $start_date = $start_date + ($day_incrementer * 60 * 60 * 24); } } while($start_date <= $end_date); return($count_leaves); } 

Я заметил, что вы также задали аналогичный вопрос в другом месте (http://stackoverflow.com/questions/10898293/how-to-get-days-of-leave-taken-in-a-given-month). Теперь я попытался погрузиться в ваш код, чтобы понять, что вы пытаетесь понять. Прошу прощения, если мой ответ не соответствует вашему желанию, так как читать мнение другого человека непросто. В принципе, я сделал, чтобы подготовить образец кода, который делает то, что вы хотите. Этот код принимает множество дат, которые определенный работник работал в течение данного месяца и года. Затем он начинает получать все рабочие даты, которые были доступны в этом месяце в этом году. Разница в обоих массивах дает даты, когда работник отсутствовал (из-за отпуска или AWOL). Публичные праздники не учитывались, но, конечно, вы можете легко изменить код, чтобы добавить это. Если вы держите даты государственных праздников в другом массиве и разницу с первым результатом, последний массив даст вам то, что вы хотите.

Теперь, только примечание о предупреждении, этот код является базовым, разность массивов не даст вам возможности, если два массива не совпадают с одним и тем же форматом даты. Лично я напишу свою собственную функцию обратного вызова сравнения, чтобы сравнить отдельные даты и передать ее в array_udiff () для максимальной уверенности. Я уверен, что вы справитесь с этим. Я только представил основы. Используйте свободно и распространяйте в зависимости от ситуации. Достаточно поговорить, см. Пример кода ниже.

 <?php /*************************************************************************** * how to get DAYS absent from working days from given date range? * @Author Prof. No Time - 12th/June/2012 ****************************************************************************/ //Leave was 10th, 13th, 23rd, 24th //Note that 01-02-2012 is NOT exactly same as 1-2-2012; Important for the array_diff fxn used below. //Note Format is dmY //Note I am assuming you have pulled this from a database of course $imaginaryWorkDatesOfWorker1 = array( '01-02-2012', '02-02-2012', '03-02-2012', '06-02-2012', '07-02-2012', '08-02-2012', '09-02-2012', '14-02-2012', '15-02-2012', '16-02-2012', '17-02-2012', '20-02-2012', '21-02-2012', '22-02-2012', '27-02-2012', '28-02-2012', '29-02-2012' ); $leaveDays1 = getLeaveDays(2, 2012, $imaginaryWorkDatesOfWorker1); displayWorkersLeaveDays($leaveDays1); //Leave was 2nd, 16th, 19th, 23rd and 26th $imaginaryWorkDatesOfWorker2 = array( '01-03-2012', '05-03-2012', '06-03-2012', '07-03-2012', '08-03-2012', '09-03-2012', '12-03-2012', '13-03-2012', '14-03-2012', '15-03-2012', '20-03-2012', '21-03-2012', '22-03-2012', '27-03-2012', '28-03-2012', '29-03-2012', '30-03-2012' ); $leaveDays2 = getLeaveDays(3, 2012, $imaginaryWorkDatesOfWorker2); displayWorkersLeaveDays($leaveDays2); ///MAIN FUNCTION TO GET LEAVE DATES/// function getLeaveDays($month, $year, $arrDatesPresent=array()){ $arrAllWorkDatesInMonth = getDatesInTheMonth($month, $year); //var_dump($arrDatesPresent); var_dump($arrAllWorkDatesInMonth); $leaveDays = array_diff($arrAllWorkDatesInMonth, $arrDatesPresent); return $leaveDays; } ///HELPER FUNCTIONS/// /** * <p>Gets all the dates in a given month in the specified year. default format dmY<p> * @param int $month * @param int $year * @param boolean $includeWeekends * @param string $format2Use * @throws Exception if invalid parameters are given * @return array: dates in the given month, in the given year */ function getDatesInTheMonth($month, $year, $includeWeekends=false, $format2Use='dm-Y') { $arrDatesInTheMonth = array(); if (empty($format2Use)) $format2Use = 'md-Y'; if (empty($month) || empty($year)){ throw new Exception("Invalid parameters given."); } else{ $fauxDate = mktime(0, 0, 0, $month, 1, $year); $numOfDaysInMonth = date('t', $fauxDate); if (!empty($numOfDaysInMonth)){ for ($day = 1; $day <= $numOfDaysInMonth; $day++){ $timeStamp = mktime(0, 0, 0, $month, $day, $year); $cdate = date($format2Use, $timeStamp); if ($includeWeekends){ $arrDatesInTheMonth[] = $cdate; } else{ if (!isWeekend($cdate)) { $arrDatesInTheMonth[] = $cdate; } } } } } return $arrDatesInTheMonth; } /** * Checks if given date is a weekend use this if you have PHP greater than v5.1. * Credit: http://stackoverflow.com/users/298479/thiefmaster * @param date $date * @return boolean */ function isWeekend($date) { return (date('N', strtotime($date)) >= 6); } /** * Checks if given date is a weekend use this if you have PHP less than v5.1. * Credit: http://stackoverflow.com/users/298479/thiefmaster * @param date $date * @return boolean */ function isWeekend2($date) { $weekDay = date('w', strtotime($date)); return ($weekDay == 0 || $weekDay == 6); } function printDates($arrDates){ foreach ($arrDates as $key => $cdate) { $display = sprintf( '%s <br />', date('[l] - jS \of F Y', strtotime($cdate)) ); echo $display; } } function displayWorkersLeaveDays($leaveDays){ echo '<div style="background-color:#CCC;margin:10px 0;">'; echo '<div>Your Leave days are as follows: </div>'; printDates($leaveDays); echo '</div>'; } 

Надеюсь это поможет.