【PHP入門】Datetimeクラスのdiffメソッドの使い方

こんにちは!エンジニアのオータケです。

DateTimeクラスには日にちの差を取得するためのdiffメソッドが存在します。

この記事では、

・DateTimeクラスとは何か
・diffメソッドの使い方
・日、月、年の差の取得方法

という基本的な内容から、

・取得した日時の差がマイナスかどうか
・diffメソッドを扱う上での注意点

などの応用的な解説していきます。

今回はそんなDateTimeクラスのdiffメソッドについてわかりやすく解説します!

目次

DateTimeクラスとは

DateTimeクラスは日付や時間の計算等、操作を行うために使います。

このDateTimeクラスはPHP5.2.0以降であれば使うことができます。

初期化方法は次のとおりです。

<?php
$date_time = new DateTime('2017-04-10');
?>

こういった書き方で初期化をすることができます。

コンストラクタの引数に渡しているのはDateTimeクラスに持たせる日時のデータになります。

次の項目ではこのDateTimeクラスを使って日時の差を求めてみましょう!

diffメソッドを使い差を求める

DateTimeクラスは先程PHP5.2.0から使うことが出来ると書きました。

しかしこのdiffメソッドPHP5.3.0からしか使うことができないため使う際には注意が必要です。

このdiffメソッドは日時の差を求めることができます。

早速どのような使い方をするのか見てみましょう。

日にちの差を得たい

この項目では日にちの差を得る場合にはどうしたらよいかを見ていきたいと思います。

<?php
$date_time = new DateTime('2017-04-10');
$date_time2 = new DateTime('2017-04-15');

$diff = $date_time->diff($date_time2);
 
echo $diff->d;
?>

実行結果:

5

まず$date_timeや$date_time2といった変数にDateTimeのインスタンスを生成して代入しています。

この段階で$date_timeには「2017-04-10」という日付を保持したDateTimeクラスのインスタンスが、
$date_time2には「2017-04-15」という日付を保持したDateTimeクラスのインスタンスが入っています。

そして$date_timeのdiffメソッドを呼び出して日付の差を求めて$diff変数に代入しています。

しかし、この$diff変数に入っている値は数値ではないためそのままでは扱うことができません。

この$diff変数に入っている値はDateIntervalクラスのインスタンスなのです。

このDateIntervalクラスには$yや$mといったプロパティをpublicで保持しているため直接アクセスすることが可能です。

コードで言えば次の部分になります。

echo $diff->d;

これで日付を取得し表示することができました。

では次に別の方法がないか見てみましょう。

<?php
$date_time = new DateTime('2017-04-10');
$date_time2 = new DateTime('2017-04-15');

$diff = $date_time->diff($date_time2);

echo $diff->format('%d');
?>

実行結果:

5

このコードではメンバに直接アクセスせずにformatメソッドを使って「書式付き」という特殊な形で取得しています。

formatメソッドの引数に「%d」と与えることで日付の差を得ることができます!

次は月の差を得たい場合にはどうするのかという点で解説をします。

月の差を得たい

この項目では月の差を得る方法を解説していきます。

まず、先程と同じようにdiffメソッドを使うという点に何ら変わりはありません。

次にdiffメソッドを使った後に取得できるDateIntervalクラスのプロパティにアクセスする方法を見てみましょう。

<?php

$date_time = new DateTime('2017-04-10');
$date_time2 = new DateTime('2017-05-15');

$diff = $date_time->diff($date_time2);

echo $diff->m;

?>

実行結果:

1

早速見ていきたいと思います。

今回のコードでは$date_time2の値が4月ではなく5月としています。

これは同じ月の場合では差がないため実行結果に0と表示されてしまうので今回はわかりやすくするために5月としました。

そして変数$diffの「m」プロパティにアクセスすることで月の差を取得することができます!

次は年の差を得たい場合はどうすればよいでしょうか?

ここまで読んで頂けている場合で察しの良い方であればどの部分が変化するか予想がつきますよね?

年の差を得たい

この項目では年の差について解説をします。

まずはコードを見てみましょう。

<?php

$date_time = new DateTime('2017-04-10');
$date_time2 = new DateTime('2018-04-15');

$diff = $date_time->diff($date_time2);

echo $diff->y;

?>

実行結果:

1

さすがに三回目の解説となるとどこが変わったか説明しなくてもわかりますよね?

年の差を求めるには「y」プロパティにアクセスすることで差を得ることができます。

差がマイナスかどうか知りたい

日付の差などを出した後にその差がマイナスかどうかを知りたい場合はどうすればよいでしょうか。

<?php
$date_time = new DateTime('2017-04-18');
$date_time2 = new DateTime('2017-04-15');

$diff = $date_time->diff($date_time2);

echo $diff->invert;
?>

実行結果:

1

差を出した際にマイナスかどうかを知りたい場合はinvertプロパティにアクセスすることでマイナスかどうかを知ることができます。

今回の場合は$date_timeの日付が大きいためdiffメソッドを呼び出した場合にinvertには1が入ります。

この1がマイナスという意味になります。

逆にそうでない場合は0が入るという仕組みになっています。

ここでdiffメソッドの使い方の解説の補足をしますが、diffメソッドの第二引数にtrueを指定することでいかなる場合でも差をマイナスとしないということを強制することができます。

$date_time->diff($date_time2, true);

このような書き方になります。

そのため日付の比較順序にかかわらず差の絶対値だけを扱いたい場合は第二引数にtrueを渡しておくと良いでしょう。

date_diffを使う方法

次にDateTimeクラスのdiffメソッドを呼び出すのではなくdate_diff関数を使う方法を解説します。

早速コードを見てみましょう

<?php
$date_time = new DateTime('2017-04-10');
$date_time2 = new DateTime('2017-04-15');

$diff = date_diff($date_time, $date_time2);

echo $diff->d;
?>

実行結果:

5

これで日付の差を得ることができました。

一番最初に解説した日付の差を得る方法と少しだけ書き方が変わっていますよね?

このdate_diff関数ですが内部的にDateTimeクラスdiffメソッドを呼び出しており結局はDateTimeクラスのdiffメソッドを使っていることに変わりはありません。

そのため特に理由がなければDateTimeクラスのdiffメソッドを使ったほうがよいでしょう。

diffメソッドにはバグがある?

diffメソッドはある問題を抱えています。

とある環境でdiffメソッドを使うと6015という日付の差がでるという問題です。

この「とある環境」についてですが

この不具合報告によるとVC6でビルドされたWindows版、PHP5.3.2の環境下で発生するということがわかります。

つまり、Mac上やLinux上では起きないというものです。

さらにVC6(VisualC++6.0)というソフトを使って構築されたPHPに限られるわけですのでこの問題によって影響を受ける人はかなり限定的で、多くはないと考えます。

まとめ

いかがでしょうか?

今回はDateTimeクラスのdiffメソッドについて解説を行いました。

diffで差を求めて、formatメソッドを使うことでその差を取得するといったことを見ていきました。

もしdiffの使い方について忘れてしまったらこの記事をぜひ思い出して下さい!

この記事を書いた人

30歳、フリーランスプログラマ。中学の頃よりプログラミングに興味を持ちゲーム開発やWebサイト構築などを経験
新しいフレームワークやライブラリに興味があり革新的な機能が含まれていると泣いて喜ぶ。

目次