如何从给定日期范围的工作日中获取缺勤天数


how to get DAYS absent from working days from given date range?

这是我为获取员工在给定日期范围内休假列表而制作的函数。如果取的叶子是一两个,那很好,但它太复杂了,因此需要很多时间来检索结果,从而导致超时错误!有什么帮助吗?

这是函数:

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("Y-m-d",$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("Y-m-d", $start_date))) >=6)) 
                       {    
                               //checking for weekends, prints only weekdays
                    echo date("Y-m-d", $start_date) . " 'n ";
                    $count_leaves++;
               }
           $start_date = $start_date + ($day_incrementer * 60 * 60 *24);              
            }
            $flag=1;

    while((date("Y-m-d",$start_date) != $row['date']))
     // loop to print $start_date,which is not equal to table date
    {
    if(!(date('N', strtotime(date("Y-m-d", $start_date))) >= 6)) 
      {
        echo  date("Y-m-d", $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("Y-m-d", $start_date))) >= 6) && ($start_date <= $end_date))
  {
            echo  date("Y-m-d", $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 d-m-Y
//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 d-m-Y<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='d-m-Y')    {
  $arrDatesInTheMonth = array();
  if (empty($format2Use)) $format2Use = 'm-d-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>';
}

希望这有帮助。