PHPのお勉強!

PHP TOP

DateInterval::__construct

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

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

説明

public DateInterval::__construct(string $duration)

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

パラメータ

duration

間隔。

最初は P から始まります。これは period を表します。 間隔の単位は、整数値の後に間隔指示子をつけて表します。 時間の要素を含む場合は、時間部分の前に文字 T を入れます。

duration の間隔指示子
間隔指示子 説明
Y
M
D
W 週。日付に変換されます。 PHP 8.0.0 より前のバージョンでは、 D と組み合わせて使えませんでした。
H 時間
M
S

いくつか簡単な例を示しましょう。 P2D は 2 日、 PT2S は 2 秒、そして P6YT5M は 6 年と 5 分を表します。

注意:

複数の単位を指定するときは、 大きな単位を左、小さな単位を右の順に書かなければなりません。 つまり年は月より先、月は日より先、日は分より先などとなります。 1 年と 4 日を表すのは P1Y4D であり、P4D1Y ではありません。

日付と時刻で間隔を指定することもできます。 1 年と 4 日をこの方式で表すと P0001-00-04T00:00:00 のようになります。 しかし、この方式では繰り返し単位以上の値を指定することはできません (たとえば 25 時間などとは指定できません)。

これらのフォーマットは » ISO 8601 duration specification に基づくものです。

エラー / 例外

duration が間隔の値としてパースできない場合、 DateMalformedIntervalStringException がスローされます。 PHP 8.3 より前のバージョンでは、Exception がスローされていました。

変更履歴

バージョン 説明
8.3.0 Exception の代わりに、 DateMalformedIntervalStringException がスローされるようになりました。
8.2.0 アクセス可能なプロパティは y から f, invert, days だけになりました。 新しい boolean プロパティ from_string もアクセス可能です。
8.0.0 W が、D と組み合わせて使えるようになりました。

例1 DateInterval オブジェクトを作成して使う例

<?php
// Create a specific date
$someDate = \DateTime::createFromFormat("Y-m-d H:i", "2022-08-25 14:18");

// Create interval
$interval = new \DateInterval("P7D");

// Add interval
$someDate->add($interval);

// Convert interval to string
echo $interval->format("%d");

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


7

例2 DateInterval の例

<?php

$interval
= new DateInterval('P1W2D');
var_dump($interval);

?>

上の例の PHP 8.2 での出力は、このようになります。:

object(DateInterval)#1 (10) {
  ["y"]=>
  int(0)
  ["m"]=>
  int(0)
  ["d"]=>
  int(9)
  ["h"]=>
  int(0)
  ["i"]=>
  int(0)
  ["s"]=>
  int(0)
  ["f"]=>
  float(0)
  ["invert"]=>
  int(0)
  ["days"]=>
  bool(false)
  ["from_string"]=>
  bool(false)
}

上の例の PHP 8 での出力は、このようになります。:

object(DateInterval)#1 (16) {
  ["y"]=>
  int(0)
  ["m"]=>
  int(0)
  ["d"]=>
  int(9)
  ["h"]=>
  int(0)
  ["i"]=>
  int(0)
  ["s"]=>
  int(0)
  ["f"]=>
  float(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)
}

上の例の PHP 7 での出力は、このようになります。

object(DateInterval)#1 (16) {
  ["y"]=>
  int(0)
  ["m"]=>
  int(0)
  ["d"]=>
  int(2)
  ["h"]=>
  int(0)
  ["i"]=>
  int(0)
  ["s"]=>
  int(0)
  ["f"]=>
  float(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)
}

参考

add a note

User Contributed Notes 14 notes

up
109
owen at beliefs.com
11 years ago
M is used to indicate both months and minutes.

As noted on the referenced wikipedia page for ISO 6801 http://en.wikipedia.org/wiki/Iso8601#Durations

To resolve ambiguity, "P1M" is a one-month duration and "PT1M" is a one-minute duration (note the time designator, T, that precedes the time value).

Using: PHP 5.3.2-1ubuntu4.19

// For 3 Months
$dateTime = new DateTime;echo $dateTime->format( DateTime::ISO8601 ), PHP_EOL;
$dateTime->add(new DateInterval("P3M"));
echo $dateTime->format( DateTime::ISO8601 ), PHP_EOL;
Results in:
2013-07-11T11:12:26-0400
2013-10-11T11:12:26-0400

// For 3 Minutes
$dateTime = new DateTime;echo $dateTime->format( DateTime::ISO8601 ), PHP_EOL;
$dateTime->add(new DateInterval("PT3M"));
echo $dateTime->format( DateTime::ISO8601 ), PHP_EOL;
Results in:
2013-07-11T11:12:42-0400
2013-07-11T11:15:42-0400

Insert a T after the P in the interval to add 3 minutes instead of 3 months.
up
11
Hernanibus
7 years ago
It is not stated, but you cannot create directly a negative interval, this is you cannot create a "-2 days" interval as:

<?
$interval = new DateInterval("P-2D");//or
$interval = new DateInterval("-P2D");
?>

Instead you have to create first the interval and then set its 'invert' property to 1, this is:

<?
$interval = new DateInterval("P2D");
$interval->invert = 1;
?>

Then you should keep in mind that this interval acts as a negative number, hence to subtract the interval from a given date you must 'add' it:

<?
$interval = new DateInterval("P2D");
$interval->invert = 1;
$date = new DateTime ("1978-01-23 17:46:00");
$date->add($interval)->format("Y-m-d H:i:s");//this is "1978-01-21 17:46:00"
?>
up
30
kuzb
13 years ago
It should be noted that this class will not calculate days/hours/minutes/seconds etc given a value in a single denomination of time. For example:

<?php
$di
= new DateInterval('PT3600S');
echo
$di->format('%H:%i:%s');

?>

will yield 0:0:3600 instead of the expected 1:0:0
up
15
admin at torntech dot com
9 years ago
Warning - despite the $interval_spec accepting the ISO 8601 specification format, it does not accept decimal fraction values with period or comma as stated in the specification.

https://bugs.php.net/bug.php?id=53831

<?php
/* Example from ISO 8601 documentation */
$interval = new DateInterval('P0.5Y');
?>

Will result in
Fatal error: Uncaught exception 'Exception' with message 'DateInterval::__construct(): Unknown or bad format (P0.5Y)'
up
20
buvinghausen at gmail dot com
12 years ago
I think it is easiest if you would just use the sub method on the DateTime class.

<?php
$date
= new DateTime();
$date->sub(new DateInterval("P89D"));
up
2