【问题标题】:subtract days if date range contains dates from a list PHP如果日期范围包含列表 PHP 中的日期,则减去天数
【发布时间】:2016-04-05 16:03:31
【问题描述】:

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

这意味着如果在假期列表中我有 25-03-2016,并且日期范围从 21-03-2016 到 25-03-2016,它应该只计算 4 天,而不是 5。

目前,我在数据库中有这张假期表:

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

不减去节假日的天数

**** UPADTE 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

由于某种原因,当我从 23/03 开始​​计算天数并避免 28/03 时,它会提供额外的折扣

【问题讨论】:

  • 如果你循环遍历日期范围并用 in_array 将每一天与列表进行比较,然后保留一个计数器?
  • 实际上我遵循@Aparna 的指示,这很有意义,但是如果范围包含假期后的天数,它不会减去
  • 它就像代码一样无法将假期中的天数识别为要比较的日期

标签: php mysql date


【解决方案1】:

您可以使用 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 服务器默认运行的时区放入时,可能很难清理。恶心!

【讨论】:

    【解决方案2】:

    首先,通过将假期列表中的日期转换为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
    }
    

    【讨论】:

    • 谢谢,我还在学习。我在哪里声明 $holiday_arr
    • 我的意思是,我该如何进行比较?
    • 一开始就声明 $holiday_arr.. 从你的数据库中获取数据并将其转换为 strtotime,然后将日期值存储在 $holiday_arr 中。我已经添加了比较行,所以你不必单独比较。
    • $days=0; $aux=strtotime($begin_date); $sqlF="SELECT * FROM tbl000_feriados"; $requestF=mysqli_query($connect,$sqlF); $holiday_arr=mysqli_fetch_array($requestF); $aux2=strtotime($holiday_arr); while ($aux &lt;=strtotime($end_date)) { if(!in_array($aux,$aux2)){ $auxday=date('N',$aux); if ($auxday!='6'&amp;&amp;$auxday!='7') { $days++; } } $aux=$aux+86400; #I add 1 day to AUX } @Aparna 它不会从假期中减去天数:(
    • 我已经编辑了我的代码,请使用该代码。希望对您有所帮助。
    【解决方案3】:

    尝试以下方法:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-02-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-30
      • 2012-10-07
      • 1970-01-01
      • 2015-05-18
      相关资源
      最近更新 更多