【问题标题】:How to return specific days between two dates in PHP如何在 PHP 中返回两个日期之间的特定日期
【发布时间】:2018-09-28 04:04:26
【问题描述】:

我今天遇到了一个可能其他人可能需要帮助的问题,所以我在这里发布答案。

客户希望我将每个星期一和星期三的日期保存在 2 个给定日期之间。

(开始日期和结束日期实际上都不是从星期一或星期三开始的)。

答案如下...

【问题讨论】:

    标签: php date


    【解决方案1】:
    • 您可以使用DateTimeDateInterval直接跳到下周的同一天,并使用diff()方法跟踪是否超过结束日期。

    代码:

    $next_monday    = new DateTime("next Monday");
    $next_wednesday = new DateTime("next Wednesday");
    $one_week = new DateInterval("P1W");
    $end_date = new DateTime(date("Y-m-d")." +100 days");
    
    
    $valid_dates = [];
    
    while(true){
        if($next_monday->diff($end_date)->invert === 1){
            break;
        }
        $valid_dates[] = $next_monday->format("Y-m-d");
        if($next_wednesday->diff($end_date)->invert === 1){
            break;
        }
        $valid_dates[] = $next_wednesday->format("Y-m-d");
        $next_monday->add($one_week);
        $next_wednesday->add($one_week);
    }
    
    
    foreach($valid_dates as $each_date){
        echo $each_date," ",date("D",strtotime($each_date)),"<br/>"; // to cross verify whether it's really Monday or Wednesday or not. 
    }
    

    输出:

    2018-10-01 Mon
    2018-10-03 Wed
    2018-10-08 Mon
    2018-10-10 Wed
    2018-10-15 Mon
    2018-10-17 Wed
    2018-10-22 Mon
    2018-10-24 Wed
    2018-10-29 Mon
    2018-10-31 Wed
    2018-11-05 Mon
    2018-11-07 Wed
    2018-11-12 Mon
    2018-11-14 Wed
    2018-11-19 Mon
    2018-11-21 Wed
    2018-11-26 Mon
    2018-11-28 Wed
    2018-12-03 Mon
    2018-12-05 Wed
    2018-12-10 Mon
    2018-12-12 Wed
    2018-12-17 Mon
    2018-12-19 Wed
    2018-12-24 Mon
    2018-12-26 Wed
    2018-12-31 Mon
    2019-01-02 Wed
    

    注意:

    您可以将86400 秒添加到开始日期的strtotime() 并运行一个循环来检查每一天(这将正常工作)。但是,如果您尝试添加 86400 * 286400 * 5 以跳过从当天起 2 或 5 天,如果您不从开始日期的 midnight 开始循环,您将面临问题。

    【讨论】:

    • 或者如果您的开始日期不是今天,第 1 行将变为(其中 X 是开始日期): $next_monday = new DateTime('XXXX-XX-XX'); $next_monday ->modify('下周一');
    【解决方案2】:

    说明

    首先将一周中所有需要的天数保存在一个数组中。我使用的是短日期形式 (D),但您可以使用长形式 (l):

    $days = ["Mon", "Wed"];   //If <PHP7 use $days = array("Mon", "Wed"); 
    

    接下来,将您的开始日期和结束日期转换为时间戳:

    $starttimestamp = strtotime($start_date);
    $endtimestamp = strtotime($end_date);
    

    接下来,执行一个 FOR 循环,每个循环增加 86400 微秒(正好是 1 天)。这将为我们在两天之间的每一天提供一个新的时间戳。为每个循环创建一个新的日期字符串:

    for(  $j=$starttimestamp;  $j<=$endtimestamp;  $j+=86400)
    {
        $tmpday = date('D',$j);
        ...
    }
    

    最后,执行 in_array 检查(例如 if needle in haystack )以查看 DAY 是否与我们所需的任何日期匹配:

    for(  $j=$starttimestamp;  $j<=$endtimestamp;  $j+=86400)
    {
        $tmpday = date('D',$j);
    
        if(in_array($tmpday, $avail_days) ){
               echo date('Y-m-d',$j);
        }
    }
    

    仅此而已。整个代码可以在下面看到。我希望这对将来的其他人有所帮助:

    完整代码

    $avail_days     = ["Mon", "Wed"];    //If <PHP7 use $days = array("Mon", "Wed"); 
    $starttimestamp = strtotime($your_start_date);
    $endtimestamp   = strtotime($your_end_date);
    
    for( $j = $starttimestamp;  $j <= $endtimestamp;  $j += 86400 )
    {
    
        $tmpday = date('D',$j);
    
        if(in_array($tmpday, $avail_days) ){
    
               echo date('Y-m-d',$j);  //This date has a day that matches your required days!
    
        }
    
    }
    

    【讨论】:

    • 如果您有任何其他建议,请随时改进。
    • 只在星期一和星期三进行迭代怎么样?找到第一个 Monday 并预先计算 Mon-Wed 和 Wed-Mon 之间的差距。现在使用 while 循环进行迭代,并使用布尔标志来切换日期以增加前一个时间戳。
    • 感谢您的意见。你有一些示例代码吗?我也很想知道我们是否可以将其扩展到更复杂的模式,例如每个第 N 个星期一,只有第一个和最后一个星期五等
    • 詹姆斯的好答案,写得很好。 但是,那些不支持[](数组)语法的服务器呢?问题/答案应该反映 PHP 版本的使用,这对于那些不了解它以及如何使用它的人来说非常重要。根据数组手册php.net/manual/en/language.types.array.php,低于 PHP 5.4 的版本不支持 [] 表示法
    • @james 我添加了我的答案来说明我的想法。对于像每个第 N 个星期一这样的情况,它变得有点棘手,但它是可以实现的。为了解决这个问题,我把它留到了这里。
    猜你喜欢
    • 2017-04-22
    • 1970-01-01
    • 2016-05-18
    • 2015-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多