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

时间:2020-12-25 08:21:41

This was the function I made for getting list of leavedays which an employee have taken in a given date range. It's fine if leaves taken are one or two, but its too complicated so that, it takes much time to retrieve results hence causes time out error! Any help?

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

This is the function:

这是功能:

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 个解决方案

#1


0  

I noticed that you also asked similar question elsewhere (http://*.com/questions/10898293/how-to-get-days-of-leave-taken-in-a-given-month). Now I tried diving into your code to get a basic understanding of what you were attempting. Kindly pardon me if my answer doesn't exactly meet your desire as it is not easy to read another person's mind. Basically, what I have done is to prepare a sample code that does what you want. This code takes an array of dates a specific worker worked in a given month and year. It then proceeds to get all the work dates that were available in that given month, that year. A difference of both arrays gives the dates the worker was absent (due to leave or AWOL). Public holidays have not been accounted for but of course, you can easily modify the code to add that. If you hold public holiday dates in another array and difference it with the first result, the final array will give you what you want.

我注意到你在其他地方也问了类似的问题(http://*.com/questions/10898293/how-to-get-days-of-leave-taken-in-a-given-month)。现在,我尝试深入了解您的代码,以便基本了解您的尝试。请原谅我,如果我的答案不能完全满足你的愿望,因为阅读别人的想法并不容易。基本上,我所做的就是准备一个能够满足您需求的示例代码。此代码采用特定工作人员在给定月份和年份中工作的日期数组。然后,它将继续获取该年当月可用的所有工作日期。两个数组的差异给出了工人缺席的日期(由于离开或AWOL)。公共假期尚未考虑,但当然,您可以轻松修改代码来添加它。如果您在另一个数组中保留公共假日日期并将其与第一个结果区分开来,最终数组将为您提供所需的内容。

Now, just a note of warning, this code is basic, array difference will fail you if the two arrays are not exactly in the same date format. Personally, I will write my own comparison callback function to compare individual dates and pass it into array_udiff() for maximum certainty. I'm pretty sure you can handle that. I have only provided the basics. Use freely and extend as appropriate to your situation. Enough talking, see the code sample below.

现在,只是注意警告,这段代码是基本的,如果两个数组不完全采用相同的日期格式,则数组差异将会失败。就个人而言,我将编写自己的比较回调函数来比较各个日期并将其传递给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://*.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://*.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>';
}

Hope this helps.

希望这可以帮助。

#1


0  

I noticed that you also asked similar question elsewhere (http://*.com/questions/10898293/how-to-get-days-of-leave-taken-in-a-given-month). Now I tried diving into your code to get a basic understanding of what you were attempting. Kindly pardon me if my answer doesn't exactly meet your desire as it is not easy to read another person's mind. Basically, what I have done is to prepare a sample code that does what you want. This code takes an array of dates a specific worker worked in a given month and year. It then proceeds to get all the work dates that were available in that given month, that year. A difference of both arrays gives the dates the worker was absent (due to leave or AWOL). Public holidays have not been accounted for but of course, you can easily modify the code to add that. If you hold public holiday dates in another array and difference it with the first result, the final array will give you what you want.

我注意到你在其他地方也问了类似的问题(http://*.com/questions/10898293/how-to-get-days-of-leave-taken-in-a-given-month)。现在,我尝试深入了解您的代码,以便基本了解您的尝试。请原谅我,如果我的答案不能完全满足你的愿望,因为阅读别人的想法并不容易。基本上,我所做的就是准备一个能够满足您需求的示例代码。此代码采用特定工作人员在给定月份和年份中工作的日期数组。然后,它将继续获取该年当月可用的所有工作日期。两个数组的差异给出了工人缺席的日期(由于离开或AWOL)。公共假期尚未考虑,但当然,您可以轻松修改代码来添加它。如果您在另一个数组中保留公共假日日期并将其与第一个结果区分开来,最终数组将为您提供所需的内容。

Now, just a note of warning, this code is basic, array difference will fail you if the two arrays are not exactly in the same date format. Personally, I will write my own comparison callback function to compare individual dates and pass it into array_udiff() for maximum certainty. I'm pretty sure you can handle that. I have only provided the basics. Use freely and extend as appropriate to your situation. Enough talking, see the code sample below.

现在,只是注意警告,这段代码是基本的,如果两个数组不完全采用相同的日期格式,则数组差异将会失败。就个人而言,我将编写自己的比较回调函数来比较各个日期并将其传递给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://*.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://*.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>';
}

Hope this helps.

希望这可以帮助。