[PHP]日付間隔関数(DateInterval)を使って簡単且つ、正確に日付の足し算、引き算をする
-
カテゴリ:
- PHP
最近になってDateInterval関数という存在を知りました。
知っている方からすると何を今更と思うかもしれませんが、日付の操作をわざわざ足し算引き算していた自分にとってはとても便利でビックリしました。
まだまだPHPの中にも自分の知らない便利な関数が眠っているなぁとしみじみ思った今日この頃です!
今回はDateInterval関数の使い方と簡単な検証を行ったので、ここにメモしておきます。
DateInterval関数とは
DateInterval関数とは日付の間隔を表すオブジェクトです。DateTime関数と併用して日付の操作に使います。
言葉で説明しても分かりずらいので使い方を見てみます。
$interval = new DateInterval(<間隔値>);
間隔値とは「P」から始まる文字列で日付間隔を指定します。
P ⇒ 間隔値の初めに必ずつける
Y ⇒ 年を指定するM ⇒ 月を指定する
D ⇒ 日を指定する
W ⇒ 週を指定する(※ D との併用不可)
T ⇒ 時分秒の指定する前に必ずつける
H ⇒ 時を指定する
M ⇒ 分を指定する
S ⇒ 秒を指定する
具体例:
<?php
$interval = new DateInterval('P1Y3DT6H');
/*結果:
object(DateInterval)#2 (16) {
["y"]=> int(1)
["m"]=> int(0)
["d"]=> int(3)
["h"]=> int(6)
["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)
}
*/
?>
上記例だと「$interval」に1年と3日と6時間の日付間隔をオブジェクトで保持したことになります。
これとDataTime関数を使って日付の足し算引き算が簡単に可能です。
<?php
// 日付の足し算
$dateTime1 = new DateTime('2020-02-07 14:59:59');
// 対象日から1年と3日、6時間前
$dateTime1->add(new \DateInterval('P1Y3DT6H'));
echo $dateTime1->format('Y-m-d: H:i:s') . PHP_EOL;
// ⇒結果: 2021-02-10: 20:59:59
//日付の引き算
$dateTime2 = new DateTime('2020-02-07 14:59:59');
// 対象日から1年と3日、6時間後
$dateTime2->sub(new \DateInterval('P1Y3DT6H'));
echo $dateTime2->format('Y-m-d: H:i:s') . PHP_EOL;
// ⇒結果: 2019-02-04: 08:59:59
?>
DateInterval関数の活用法
月またぎ、うるう年
DateInterval関数は月またぎの日付の制御やうるう年の考慮がとても簡単です。
<?php
// 月またぎ
$dateTime = new DateTime('2019-12-31 22:00:00');
$dateTime->add(new \DateInterval('PT3H'));
echo $dateTime->format('Y-m-d: H:i:s') . PHP_EOL;
// ⇒結果: 2020-01-01: 01:00:00
// うるう年
$dateTime1 = new DateTime('2020-02-28 23:59:59');
$dateTime1->add(new \DateInterval('PT1S'));
echo $dateTime1->format('Y-m-d: H:i:s') . PHP_EOL;
// ⇒結果: 2020-02-29: 00:00:00
$dateTime2 = new DateTime('2019-02-28 23:59:59');
$dateTime2->add(new \DateInterval('PT1S'));
echo $dateTime2->format('Y-m-d: H:i:s') . PHP_EOL;
// ⇒結果: 2019-03-01: 00:00:00
?>
使い回しが楽
DateInterval関数は日付間隔をオブジェクトとして持っているので、使い回しに向いています。
<?php
$dateTime1 = new DateTime('2020-02-07 00:00:00');
for ($i = 1; $i <= 5; $i++) {
$dateTime1->add(new \DateInterval('P2D'));
echo $dateTime1->format('Y-m-d: H:i:s') . PHP_EOL;
}
?>
/*結果:
2020-02-09: 00:00:00
2020-02-11: 00:00:00
2020-02-13: 00:00:00
2020-02-15: 00:00:00
2020-02-17: 00:00:00
*/
上記の例のように2日間ごとの日付を繰り返し取得する時などに便利です。
DateInterval関数の注意点
DateInterval関数は使用の際にいくつか気を付けたいポイントがります。
インスタンス作成時は引数に注意
newするときは引数は必須です。また数値型や日付型の引数もNGです。
<?php
$dateTime = new DateTime(); // 引数無し
$dateTime = new DateTime(20200207); // 引数が文字列ではない
// ⇒結果: 上記例はすべて実行エラーになります。
?>
間隔値の指定準に注意
間隔値にはいくつか規則と制約があるります。
まず第一に最初に「P」が付いていなかったり、時分秒の前に「T」が無くてもエラーになります。
さらに指定する際は優先順位があり、優先順位を間違えて指定してもエラーになってしまいます。
・優先順位
Y(年) > M(月) > D(日) = W(週) > H(時) > M(分) > S(秒)
<?php
$dateTime = new DateTime('1YT6H'); // 間隔値の先頭に「P」が無い
$dateTime = new DateTime('P2D6H'); // 時分秒の前に「T」が無い
$dateTime = new DateTime('P3D2Y5H'); // 優先準備間違い「Y」の前に「D」がある
// ⇒結果: 上記例はすべて実行エラーになります。
?>
使うには決まりがありますが、理解するととても便利な関数です!