I noticed that you also asked similar question elsewhere (http://stackoverflow.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.
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.
<?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>';
}
Hope this helps.