如果日期范围包含PHP列表中的日期,则减去天数


subtract days if date range contains dates from a list PHP

我有一个计算,它给出了两个日期之间的总劳动天数。但是,如果日期范围包含列表中的任何日期(假日),我必须从总天数中减去假日中的每一天。

这意味着,如果在假期列表中,我的日期是2016年3月25日,日期范围从2016年3日21日到2016年3月25日,那么它应该只计算4天,而不是5天。

目前,我在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

总劳动天数来自这个函数:

$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
}

更新

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

它不减去假日的天数

****截至2

这个问题与tbl000_feriados表中的讲座有关,因为如果我手动将数据放入数组中

 array(2016-03-25)

例如,它使减法正确。

从tbl000_feriados 读取日期有问题

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

*****更新3

出于某种原因,当我从2003年3月23日开始计算天数时,它会有一个传统的折扣,并且避免了2003年28日的

您可以使用mysql between运算符查找给定日期之间的假期数量(在您的情况下为$begin_date和$end_date)

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

只要数据库中的Date是datedatetime类型,mysql就会知道如何处理它。但是,请注意,您的欧洲日期格式(dd-mm-yyyy)虽然可以说比愚蠢的美国mm-dd-yyyy格式更符合逻辑,但可能无法正确地测试为日期。我强烈推荐更普遍一致的YYYY-MM-DD格式(它还有一个额外的好处,即时间顺序与词典顺序相匹配,这意味着按字母顺序排列的日期列表也将按时间顺序排列!)

将日期作为日期保存在数据库中是你能做的最聪明的事情之一。你不仅能够像这样进行以日期为中心的比较,而且你还可以很好地开始考虑支持——或者至少明确地设置——时区。我提醒所有与日期相关的程序的开发人员使用明确的时区启动。如果你在表中输入了日期,但没有应用正确的时区,那么当你稍后尝试处理时区时,可能很难清理,而且数据没有作为mysql服务器默认运行的时区输入。冰冷!

首先,通过将日期转换为strtotime格式,在假日列表中创建一个日期数组。

$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)) { 

然后将其与新数组进行比较,如果假日列表数组中不存在此日期,则从这里开始

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

当Aux小于结束时,我验证一周中的哪一天是这个

    $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
}

尝试以下操作:

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