PHP Velho Oeste 2024

DatePeriod::__construct

(PHP 5 >= 5.3.0, PHP 7, PHP 8)

DatePeriod::__construct新しい DatePeriod オブジェクトを作成する

説明

public DatePeriod::__construct(
    DateTimeInterface $start,
    DateInterval $interval,
    int $recurrences,
    int $options = 0
)
public DatePeriod::__construct(
    DateTimeInterface $start,
    DateInterval $interval,
    DateTimeInterface $end,
    int $options = 0
)
警告
public DatePeriod::__construct(string $isostr, int $options = 0)

このコンストラクタのバリエーションは、推奨されなくなりました。 代わりに、DatePeriod::createFromISO8601String() を使いましょう。

新しい DatePeriod オブジェクトを作成します。

DatePeriod オブジェクトは、 たくさんの DateTimeImmutableDateTime を生成するイテレータとして使えます。 パラメータ start, interval, end, および recurrences の数を指定できます。

返されるオブジェクトのクラスは、 start の祖先になるオブジェクトで、 DateTimeImmutableDateTime に等しくなります。

パラメータ

start

期間の開始日。デフォルトでは、 結果セットに含まれています。

interval

期間内での発生間隔。

recurrences

反復回数。 返される結果の数は、この値よりひとつ大きくなります。 なぜなら、デフォルトでは結果セットに開始日が含まれているからです。 0 より大きな値でなければいけません。

end

期間の終了日。 デフォルトでは、結果セットから除外されています。

isostr

» ISO 8601 repeating interval specification のサブセットを指定します。

PHP がサポートしていない、サブセットの機能の例を以下に示します:

  1. 0回の繰り返し (R0/)
  2. UTC 以外の時間のオフセット(Z)。 たとえば +02:00 のようなものです。
options

開始日と終了日に関する振る舞いを制御するビットフィールド

DatePeriod::EXCLUDE_START_DATE を指定すると、開始日を期間の結果セットから除外できます。

DatePeriod::INCLUDE_END_DATE を指定すると、終了日を期間の結果セットに含めることができます。

エラー / 例外

isostr が有効な ISO 8601 の期間としてパースできない場合、 DateMalformedPeriodStringException をスローします。 これより前のバージョンでは、Exception がスローされていました。

変更履歴

バージョン 説明
8.3.0 Exception ではなく、 DateMalformedPeriodStringException がスローされるようになりました。
8.2.0 定数 DatePeriod::INCLUDE_END_DATE が追加されました。
7.2.19, 7.3.6, 7.4.0 recurrences は、0 より大きな値が必須になりました。

例1 DatePeriod の例

<?php
$start
= new DateTime('2012-07-01');
$interval = new DateInterval('P7D');
$end = new DateTime('2012-07-31');
$recurrences = 4;
$iso = 'R4/2012-07-01T00:00:00Z/P7D';

// これらはすべて同じ意味です
$period = new DatePeriod($start, $interval, $recurrences);
$period = new DatePeriod($start, $interval, $end);
$period = new DatePeriod($iso);

// DatePeriod の反復処理をすると、
// 期間内のすべての発生日が表示されます。
foreach ($period as $date) {
echo
$date->format('Y-m-d')."\n";
}
?>

上の例の出力は以下となります。

2012-07-01
2012-07-08
2012-07-15
2012-07-22
2012-07-29

例2 DatePeriod で DatePeriod::EXCLUDE_START_DATE を使う例

<?php
$start
= new DateTime('2012-07-01');
$interval = new DateInterval('P7D');
$end = new DateTime('2012-07-31');

$period = new DatePeriod($start, $interval, $end,
DatePeriod::EXCLUDE_START_DATE);

// DatePeriod の反復処理をすると、
// 期間内のすべての発生日が表示されます。
// ただし、今回の場合は 2012-07-01 が表示されません。
foreach ($period as $date) {
echo
$date->format('Y-m-d')."\n";
}
?>

上の例の出力は以下となります。

2012-07-08
2012-07-15
2012-07-22
2012-07-29

例3 一年間に含まれる、月の最後の木曜日を全て表示する、DatePeriod の例

<?php
$begin
= new DateTime('2021-12-31');
$end = new DateTime('2022-12-31 23:59:59');

$interval = DateInterval::createFromDateString('last thursday of next month');
$period = new DatePeriod($begin, $interval, $end, DatePeriod::EXCLUDE_START_DATE);

foreach (
$period as $dt) {
echo
$dt->format('l Y-m-d'), "\n";
}
?>

上の例の出力は以下となります。

Thursday 2022-01-27
Thursday 2022-02-24
Thursday 2022-03-31
Thursday 2022-04-28
Thursday 2022-05-26
Thursday 2022-06-30
Thursday 2022-07-28
Thursday 2022-08-25
Thursday 2022-09-29
Thursday 2022-10-27
Thursday 2022-11-24
Thursday 2022-12-29

注意

ISO 8601 のセクション 4.5 "Recurring time interval" に記載されている無限回数の繰り返しには対応していません。 つまり、isostr"R/..." を渡したり endnull を渡したりしても動作しません。

add a note add a note

User Contributed Notes 4 notes

up
36
simon dot kohlmeyer at mayflower dot de
13 years ago
I found two things useful to know that aren't covered here.

1. endDate is excluded:

<?php
$i
= new DateInterval('P1D');
$d1 = new Datetime();
$d2 = clone $d1; $d2->add($i);
foreach(new
DatePeriod($d1, $i, $d2) as $d) {
    echo
$d->format('Y-m-d H:i:s') . "\n";
}
?>

Will output:
2010-11-03 12:39:53

(Another one because I got it wrong at first)
2. For the first form, recurrences really means REcurrences, not occurences.

<?php
$i
= new DateInterval('P1D');
$d = new Datetime();
foreach(new
DatePeriod($d, $i, 1) as $d) {
    echo
$d->format('Y-m-d H:i:s') . "\n";
}
?>

Will output:
2010-11-03 12:41:05
2010-11-04 12:41:05
up
14
lars at hp-designs dot com
11 years ago
When you add the time 23:59:59 to the end DateTime object something like the following then the end date will be included in the period:

<?php
$date_start
= new DateTime('2012-03-12');
$date_end = new DateTime('2012-03-22 23:59:59');

$interval = '+2 days';
$date_interval = DateInterval::createFromDateString($interval);

$period = new DatePeriod($date_start, $date_interval, $date_end, DatePeriod::EXCLUDE_START_DATE);

foreach(
$period as $dt) {
echo
$dt->format('d/m');
}
?>

OUTPUT:
14/03
16/03
18/03
20/03
22/03
up
0
bill at bwi dot com
2 years ago
With reference to the Changelog above, 'recurrences' must be greater than 0 now.

This was not the case in PHP5 ( >= 5.3.0). A foreach loop over a DatePeriod with recurrences == 0 would
execute one time. A function could accept a $count parameter which represented the number of times to execute
the code in a foreach loop, and then initialize a DatePeriod with 'recurrences' == ($count-1) to get the desired
number of iterations.

The following example adds a special case for PHP7 and above to handle the situation where a single
iteration is desired.

Note that an alternative solution to subracting 1 from the desired count is to subtract one month from the desired starting month,      
and then intialize the DatePeriod with the option DatePeriod::EXCLUDE_START_DATE.

<?php
       
// displayCalender() is a stub.
        // In a real application, this would generate a displayable calendar for the specified month.
        //
        // $tp is a DateTime object used to specify the month for which a calendar will be displayed
       
function displayCalendar($tp)
        {
               
$format = "F, Y";
                echo
"Display Calendar for " . $tp->format($format) . "\n";
        }

       
// $date is the first month to show
        // $count is the number of months to show
        // NOTE: the number of "recurrences" is one less than the number of months to display
       
function showMonths($date = false, $count = 1)
        {
               
$format = "Y-m-d 00:00:00";
               
$init = ($date ? $date : date($format));
               
$one_month = new DateInterval("P1M");

               
// get the starting month and day
               
$start = new DateTime($init);

                echo
"Show $count month" . ($count > 1 ? "s" : "") . "\n";
               
//check for PHP7 or greater
               
if ($count == 1 && (substr(phpversion(), 0, 1) >= 7) )
                {
                       
// Special case for PHP7 when $count == 1
                       
displayCalendar($start);
                }  
                else
                {
                       
// PHP5 does not need special case, because 0 is accepted value
                        //      for number of recurrences
                       
$time_period = new DatePeriod($start, $one_month, ($count-1));
                        foreach (
$time_period as $tp)
                        {
                               
displayCalendar($tp);
                        }
                }
                echo
"\n";
        }
       
       
// Show calendar for specific month
       
$first_month = "2021-11";
       
showMonths($first_month);
       
       
// Show calendars for a full year
       
$first_month = "2021-01";
       
showMonths($first_month, 12);
?>

The above example will output:

Show 1 month
Display Calendar for November, 2021

Show 12 months
Display Calendar for January, 2021
Display Calendar for February, 2021
Display Calendar for March, 2021
Display Calendar for April, 2021
Display Calendar for May, 2021
Display Calendar for June, 2021
Display Calendar for July, 2021
Display Calendar for August, 2021
Display Calendar for September, 2021
Display Calendar for October, 2021
Display Calendar for November, 2021
Display Calendar for December, 2021
up
0
youssef dot benhssaien at gmail dot com
4 years ago
The parameter isostr should accept an ISO 8601 format, but doing this is not work :
<?php
      $dateStart
= date_create('first day of next month this year');

     
$isoStr = $dateStart ->format(DateTimeInterface::ISO8601);
     
$datePeriod = new DatePeriod("R10/{$isoStr}/P1M");
    
// Throw Exception : DatePeriod::__construct(): Unknown or bad format (R10/2020-02-01T22:52:26+0000Z/P1M)
    
     // While doing it by this way works
   
$datePeriod = new DatePeriod($dateStart , \DateInterval::createFromDateString("+1 month"), 10);
?>
To Top