【问题标题】:return array of dates from a given range on specific days of the week with certain days excluded返回一周中特定日期给定范围内的日期数组,排除特定日期
【发布时间】:2013-05-22 15:34:15
【问题描述】:

我正在尝试创建一个递归函数,以根据某些规则生成一组有效日期。

到目前为止我已经有了这个功能

function progDateRange($date, $end_date, $wkDays, $excluded, $dates = array())
{
    $valid_date = false;
    $max_date = new DateTime(date('Y-m-d'));
    $max_date->add(new DateInterval('P2Y'));
    $max_date = $max_date->format('Y-m-d');

    // is this date before the end date or the max date
    if(strtotime($date) <= strtotime($end_date) && strtotime($date) <= strtotime($max_date))
    {
        if(!in_array($date, $excluded))
        {
            foreach($wkDays as $day => $val)
            {
                // is this date a valid weekday start
                if(date("l", strtotime($date)) == $day) {
                    // successful date
                    $valid_date = true;
                }
            }
            if($valid_date) {
                array_push($dates, $date);
            }
        }
        $next_day = new DateTime($date);
        $next_day->add(new DateInterval('P1D'));
        progDateRange($next_day->format('Y-m-d'), $end_date, $wkDays, $excluded, $dates);
    } else {
        return $dates;
    }
}

我在单独的页面上使用它

$datesArray = progDateRange($date_start, $date_end, $wkDays, $excluded);

我传入开始日期、结束日期、有效日期所在的工作日数组以及要排除的日期数组。

如果我在这样的函数内print_r()

$next_day = new DateTime($date);
$next_day->add(new DateInterval('P1D'));
print_r($dates);
progDateRange($next_day->format('Y-m-d'), $end_date, $wkDays, $excluded, $dates);

每个循环都会打印出数组并继续成功添加,但由于某种原因,当我尝试在单独的页面上使用 print_r($datesArray) 时,没有任何输出,甚至没有一个空白数组,我根本不知道为什么.

我敢肯定这会很愚蠢,因为该函数似乎在大多数情况下都可以工作,只是在返回数据时遇到了问题。

我错过了什么?

我也刚刚尝试在 return 语句之前执行print_r(),这将返回我想要得到的确切数组。调用函数的页面上数据的返回/检索肯定有问题...

编辑

正如我之前没有提到的,这里是 $wkDays$excluded 的示例 var 转储

$wkDays 产生

array(6) {
  [0]=>
  string(6) "Monday"
  [1]=>
  string(7) "Tuesday"
  [2]=>
  string(9) "Wednesday"
  [3]=>
  string(8) "Thursday"
  [4]=>
  string(6) "Friday"
  [5]=>
  string(6) "Sunday"
}

$excludes 可能是这样的

array(23) {
  [0]=>
  string(10) "2013-04-22"
  [1]=>
  string(10) "2013-04-29"
  [2]=>
  string(10) "2013-05-13"
  [3]=>
  string(10) "2013-05-27"
  [4]=>
  string(10) "2013-06-03"
  //...
}

一个示例调用可能是这样的;

progDateRange("2013-05-01", "2017-05-01", array("Monday", "Wednesday"), array("2013-06-12", "2013-06-19"));

解决方案

以 Jacks 为例,我不得不做一些调整,最终得到了这个;

function progDateRange($date, $end_date, $wkDays, $excluded)
{
    $dates = array();
    $todays_date = strtotime(date("Y-m-d"));
    $current_date = strtotime($date);
    $max_date = min(strtotime('+2 years'), strtotime($end_date));

    while ($current_date < $max_date)
    {
        if (!in_array($date, $excluded) && in_array(date('l', $current_date), $wkDays) && $current_date > $todays_date) {
            array_push($dates, $date);
        }
        $current_date = strtotime('+1 day', $current_date);
        $date = date('Y-m-d', $current_date);
    }
    return $dates;
}

【问题讨论】:

  • $max_date = date('Y-m-d', strtotime('+2 years')) 看起来比你现在做的要容易得多:) 为什么递归?

标签: php arrays date


【解决方案1】:

最后一次递归调用没有返回$dates的值,即函数结果为空;也就是说,你甚至不需要递归:

function progDateRange($date, $end_date, array $wkDays, array $excluded)
{
    $dates = array();

    $current_date = strtotime($date);
    $max_date = min(strtotime('+2 years'), strtotime($end_date));
    $dow = array_keys($wkDays);

    while ($current_date < $max_date) {
        if ($excluded && in_array($date_formatted, $excluded, true)) {
            continue;
        }
        if (in_array(date('l'), $dow, true)) {
            array_push($dates, $date);
        }
        $current_date = strtotime('+1 day', $current_date);
        $date = date('Y-m-d', $current_date);
    }

    return $dates;
}

【讨论】:

  • 感谢对函数的重写,它并没有按原样工作,但稍作调整,我得到了我想要的,现在它正在工作!
【解决方案2】:

您需要存储递归调用的结果。像这样:

$dates = array_merge(
    $dates,
    progDateRange($next_day->format('Y-m-d'), $end_date, $wkDays, $excluded, $dates)
);

或者,正如您可能已经尝试过的那样(看起来像),使用 $dates 作为引用参数调用。注意参数名称前的&amp;

function progDateRange($date, $end_date, $wkDays, $excluded, &$dates = array())

但我更喜欢第一种方法

【讨论】:

  • 我已经尝试过您提到的第二种解决方案,但是再次没有返回任何内容。第一个解决方案让我有点困惑,除了添加到变量之外,我从来没有使用过 +=,这将如何与数组一起使用?
  • Array Operators - PHP Manual 但我明白了,+ 不适合这里
  • 哦,好的,很高兴知道。不幸的是,在实际尝试时,我得到了Fatal error: Unsupported operand types...。您编辑的解决方案也返回空白...
  • Your edited solution also returns blank. 这是什么意思?
  • 顺便说一句,我认为这里没有递归的理由。我会重新设计那个功能
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多