如何在给定日期范围内的工作日内缺少DAYS?

时间:2012-06-08 10:27:46

标签: php

这是我为获取员工在给定日期范围内的休假日列表所做的功能。如果采取的叶子是一个或两个,这很好,但它太复杂,以至于检索结果需要很长时间,因此导致超时错误!有帮助吗?

这是功能:

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);
 }

1 个答案:

答案 0 :(得分:0)

我注意到你在其他地方也问了类似的问题(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>';
}

希望这有帮助。