每月创建PHP DatePeriod

时间:2015-07-22 14:38:13

标签: php datetime

以下代码根据用户输入创建PHP DatePeriod对象。循环的第一次迭代运行,但第二次返回此错误:PHP Fatal error: Call to a member function format() on a non-object。我无法看到导致错误的原因。

我希望用它来填充具有不规则重复日期的数组。即。 “本月第二个星期日”,“本月最后一个星期五”。

$raw_dates['starting'] = DateTime::createFromFormat( 'Ymd', $starting_date );
$raw_dates['ending'] = DateTime::createFromFormat( 'Ymd', $ending_date );

if ( 'Monthly' == $frequency ) {
    $recurances = $raw_dates['starting']->diff($raw_dates['ending']);
    $recurances = $recurances->m;
    $i = 'P1M';
    $interval = new DateInterval( $i );
    $period = new DatePeriod( $raw_dates['starting'], $interval, $recurances );
    $string = $monthly_recurring_week.' '.$monthly_recurring_day.' of ';

    foreach ( $period as $date ) {
        $string .= $date->format( 'F Y');
        $occurance = strtotime( $string );
        $raw_occurance = DateTime::createFromFormat( 'U', $occurance );
        $finished_date = $raw_occurance->format( 'Ymd' );
        $occurances[] = array(
            'sm_set_starts' => $finished_date,
            'sm_set_ends' => $finished_date
        );
    }

}

这一行是在第二次迭代中抛出错误的那一行:$finished_date = $raw_occurance->format( 'Ymd' );但我认为我的DatePeriod对象可能更早。

这是DatePeriod对象的转储:

object(DatePeriod)#51 (6) {
  ["start"]=>
  object(DateTime)#53 (3) {
    ["date"]=>
    string(26) "2015-07-01 14:34:01.000000"
    ["timezone_type"]=>
    int(3)
    ["timezone"]=>
    string(3) "UTC"
  }
  ["current"]=>
  NULL
  ["end"]=>
  NULL
  ["interval"]=>
  object(DateInterval)#55 (15) {
    ["y"]=>
    int(0)
    ["m"]=>
    int(1)
    ["d"]=>
    int(0)
    ["h"]=>
    int(0)
    ["i"]=>
    int(0)
    ["s"]=>
    int(0)
    ["weekday"]=>
    int(0)
    ["weekday_behavior"]=>
    int(0)
    ["first_last_day_of"]=>
    int(0)
    ["invert"]=>
    int(0)
    ["days"]=>
    bool(false)
    ["special_type"]=>
    int(0)
    ["special_amount"]=>
    int(0)
    ["have_weekday_relative"]=>
    int(0)
    ["have_special_relative"]=>
    int(0)
  }
  ["recurrences"]=>
  int(3)
  ["include_start_date"]=>
  bool(true)
}

1 个答案:

答案 0 :(得分:0)

根据John Conde建议使用DateTime并根据Sverri M Olsen's回复this SO question,我发现了DateInterval:createFromDateString

这是此问题的工作代码

if ( 'Monthly' == $frequency ) {
    $string = $monthly_recurring_week.' '.$monthly_recurring_day.' of next month';
    $interval = DateInterval::createFromDateString( $string );
    $period   = new DatePeriod($raw_dates['starting'], $interval, $raw_dates['ending'], DatePeriod::EXCLUDE_START_DATE);

    foreach($period as $time) {
        $occurances[] = array(
            'sm_set_starts' => $time->format( 'Ymd' ),
            'sm_set_ends' => $time->format( 'Ymd' )
        );
    }

}

我认为值得注意的是,当循环遍历DatePeriod对象时,日期字符串的“下个月”部分是相对于当前间隔,而不是开始日期,这是我在原始帖子中所做的。