DateIntervalとdiffで期間と日数を正しく扱う

DateIntervalとは、二つの日付の差や一定の期間を表すオブジェクトです。DateTimeのdiffで差分を取り出したり、addやsubで期間を足し引きするのに使います。

diffは二つの日付の差をDateIntervalで返す

二つの日付の差を求めたいとき、タイムスタンプの引き算で秒数を出して 86400 で割る、という力技をやりがちですが、DateTime の diff メソッドを使うほうが素直で安全ですね。差を DateInterval オブジェクトで返してくれます。

$from = new DateTimeImmutable('2026-07-01');
$to   = new DateTimeImmutable('2026-07-22');
$diff = $from->diff($to);
echo $diff->days;  // 21(総日数)
echo $diff->d;     // 21(年月を除いた日部分)

ここで注意したいのが days と d の違いです。days は総日数、d は「年・月を差し引いた残りの日」なので、月をまたぐと値が変わります。日数計算では days を使うのが安全ですね。

年月日をまたぐと d と days がずれる

たとえば1か月と3日離れていると、d は 3、days は 34 前後になります。ここを取り違えると経過日数の集計がおかしくなるので、意図を確認しておきたいところです。

$a = new DateTimeImmutable('2026-01-15');
$b = new DateTimeImmutable('2026-02-18');
$diff = $a->diff($b);
echo $diff->m . 'か月' . $diff->d . '日'; // 1か月3日
echo $diff->days . '日';                  // 34日

DateIntervalで期間を足し引きする

DateInterval は ISO8601 の期間表記で自分でも作れます。P が期間、T 以降が時刻部分です。add / sub と組み合わせて「30日後」「2時間前」のような計算に使えますね。Immutable なら結果を戻り値で受けます。

$now = new DateTimeImmutable('2026-07-22 10:00');
$after = $now->add(new DateInterval('P30D'));   // 30日後
$before = $now->sub(new DateInterval('PT2H'));  // 2時間前
echo $after->format('Y-m-d');  // 2026-08-21
echo $diff = $now->diff($after)->format('%a日'); // 30日

まとめ

期間の計算は自前の秒数演算よりも diff と DateInterval に任せたほうが、うるう年や月末の扱いを含めて安全だと思います。総日数なら days、年月を除いた端数なら d、という使い分けだけは取り違えないよう気をつけたいですね。format の %a も総日数を出せるので、表示のときに便利です。

よくある質問

Q. daysとdはどう違うのですか?
A. daysは二つの日付の総日数、dは年と月を差し引いた残りの日数です。経過日数を出したいときはdaysを使います。

Q. 期間を足し引きするにはどうしますか?
A. new DateInterval(‘P30D’)のようにISO8601表記で期間を作り、addやsubに渡します。Immutableなら結果は戻り値で受けます。

Q. うるう年や月末はdiffで正しく扱えますか?
A. diffとDateIntervalに任せれば内部で考慮されるので、自前の秒数計算よりも安全です。

類似投稿

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です