简体   繁体   中英

subtract days if date range contains dates from a list PHP

I have a calculation that gives the total amount of laboral days between 2 dates. However, if the range of dates contains any date present in a list (holidays), I must subtract each day from holidays from the total amount of days.

It means if in the list of holidays i have the 25-03-2016, and the range of dates go from 21-03-2016 to 25-03-2016, it should count only 4 days, not 5.

At the moment, I have this table of holidays in the DB:

Date
01-01-2016
25-03-2016
27-06-2016
16-07-2016
15-08-2016
19-09-2016
10-10-2016
31-10-2016
01-11-2016
08-12-2016

And the total amount of laboral days comes from this function:

$days=0;
$aux=strtotime($begin_date); #Aux for days
while ($aux <=strtotime($end_date)) { #While the Aux is less than the end, I verify wich day of the week is this
    $auxday=date('N',$aux);
    if ($auxday!='6'&&$auxday!='7') { # if is different of 6 or 7, (saturday and sunday) I add 1 to the total amount of days
        $days++;
    }
    $aux=$aux+86400; #I add 1 day to AUX
}

Update

    $sqlF="SELECT * FROM tbl000_feriados";
    $requestF=mysqli_query($connect,$sqlF);
    $holidays=mysqli_fetch_array($requestF);
    foreach($holidays as $arr){
    $holiday_arr[] = strtotime($arr);
    }
    $days=0;
    $aux=strtotime($begin_date);
    while ($aux <=strtotime($end_date)) { 
    if(!in_array($aux,$holiday_arr)){
    $auxday=date('N',$aux);
    if ($auxday!='6'&&$auxday!='7') { 
    $days++;
    }
    }
    $aux=$aux+86400; 
}

It do not subtract the days of the holidays

**** UPADTE 2

The problem is related with the lecture from the table tbl000_feriados, because if i put the data manually into the array

 array(2016-03-25)

for instance, it makes the subtract correctly.

something is going wrong about reading the date from tbl000_feriados

$sqlF="SELECT * FROM tbl000_feriados";
$requestF=mysqli_query($connect,$sqlF);
$holidays=mysqli_fetch_array($requestF);

***** UPDATE 3

For some reason, it make an aditional discount when im counting days from 23/03 and avobe 28/03

You might be able to find the number of holidays which fall between given dates ( $begin_date and $end_date in your case) with the mysql BETWEEN operator:

SELECT COUNT(*) from holidays where Date between Date('2016-02-05') and date('2016-04-01');

As long as the Date in your databse is a date or datetime type in the database, mysql will know how to process it. Note however that your european date format (dd-mm-yyyy) , while arguably more logical than the goofy US mm-dd-yyyy format, may not properly test as a date. I highly recommend the more universally consistent YYYY-MM-DD format ( which has the additional benefit that chronological order matches lexicographical order, which means an alphabetized date list will also be in chronoligical order! )

Keeping dates as dates in the database is one of the smartest things you can do. Not only are you able to make date-centric comparisons like this, but you'll also be in good shape to start thinking about supporting - or at least explicitly setting - timezones. I caution all developers of date-related programs to start with explicit timezones. If you put dates into your table but don't apply the correct timezone, it can be hard to clean up when you try to handle timezones later and the data wasn't put in as the timezone the mysql server ran in by default. Icky!

First, make an array of the dates in holiday list by converting them into strtotime format.

$days=0;
$holidays = array('2016-01-01', '2016-03-25');
foreach($holidays as $arr){
  $holiday_arr[] = strtotime($arr);
}
$begin_date = '2016-01-01';
$end_date = '2017-01-01';
$aux=strtotime($begin_date); #Aux for days
while ($aux <=strtotime($end_date)) { 

then compare it with the new array, if this date not exists in holiday list array then, proceed from here

if(!in_array($aux,$holiday_arr)){

While the Aux is less than the end, I verify wich day of the week is this

    $auxday=date('N',$aux);
    if ($auxday!='6'&&$auxday!='7') { # if is different of 6 or 7, (saturday and sunday) I add 1 to the total amount of days
        $days++;
}
    }
    $aux=$aux+86400; #I add 1 day to AUX
}

Try the following:

$holidays = array('2016-01-01', '2016-03-25');

$begin_date = new DateTime('2016-01-01');
$end_date = new DateTime('2017-01-01');
$exclude = 0;

// Loop over holidays to find out whether they are in the range
foreach ($holidays as $holiday) {
    if (isWithinDates(new DateTime($holiday), $begin_date, $end_date)) {
        $exclude++;
    }
}

function isWithinDates(DateTime $date, DateTime $start, DateTime $end)
{
    return $date >= $start && $date <= $end;
}

// Get the amount of days between our start date and the end date
// and subtract the amount of days that we know to be holidays
$interval = $begin_date->diff($end_date)->days - $exclude;

var_dump($interval);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM