PHPに限らず、日付を比較するケースはよくありますね。
- 日付を比較し、過去か未来かを判定
- 日付の差を計算(2015年7月21日 - 2010年3月10日 = 5年4ヶ月11日)
srttotime()
がメジャーですが2038年問題など問題もあるため、日付の計算はDateTime
クラスを使うよう推奨されています。
とりあえず、両方のパターンをご紹介します。
目次
関数を使わずに日付を比較
単純な比較なら、特に日付関数も使わずに文字列同士でも可能です。
日付を比較し過去か未来かを判定
1 2 3 4 5 6 7 8 9 10 11 12 |
$day1 = '2015-09-24'; $day2 = '2015-05-11'; if ($day1 === $day2) { echo '今日です。'; } else { if ($day1 > $day2) { echo '過去の日付です。'; } else { echo '未来の日付です。'; } } |
過去の日付です。
strtotime関数で日付を比較
英文形式の日時をUNIXタイムスタンプに変換してくれます。
何のことかピンと来ませんが、日付の差分を計算したり、1週間後の日付を取得したりと日付の計算の時によく使われますね。
日付の差分が何日かを計算する
1 2 3 4 |
$day1 = strtotime('2015-03-29'); $day2 = strtotime('2015-05-11'); echo ($day2 - $day1) / (60 * 60 * 24). '日': // 43日 |
上記の例だと、以下のように処理されています。
2015-03-29をstrtotime関数でUNIXタイムスタンプに変換→「1427554800」
2015-05-11をstrtotime関数でUNIXタイムスタンプに変換→「1431270000」
(1431270000 – 1427554800) / (60 * 60 * 24). ‘日’;
→UNIXタイムスタンプの差を引き算で計算し、その結果に60(秒)*60(分)*24(時間)を掛けた数で割ることで、日数の差が出る。
A. 3715200 ÷ 86400 = 43(日)
strtotime関数の問題
しかし、strtotime()
は環境によっては2038年問題があったり何かと問題を引き起こすため、日付の計算はDateTime
クラスを使うようマニュアルでも推奨されています。
注意:
この関数を使って日付の足し算や引き算を行うことはおすすめできません。
PHP 5.3 以降なら DateTime::add() や DateTime::sub() を、そして PHP 5.2 なら DateTime::modify() を使いましょう。
出典:PHPマニュアルより
PHP5.2以降よりDateTime
クラスがサポートされていますので、そちらを使うようにしましょう。
DateTimeクラスで日付比較
PHP5.1以前の古いバージョンでなければ、DateTime
クラスを使うようにしましょう。
diffを使った比較
1 2 3 4 5 6 |
$day1 = new DateTime('2015-09-24'); $day2 = new DateTime('2015-05-11'); $interval = $day1->diff($day2); echo $interval->format('%a日'); |
136日
日付の差が出ましたが、diff
やformat('%a')
など見慣れない記号も出てきました。
説明
DateTime
クラスでの日付の比較は以下のようになっています。
$day1 = new DateTime(‘2015-09-24’);
$day2 = new DateTime(‘2015-05-11’);
- まず、比較する2つの日付の
DateTime
オブジェクトを作る - そしてそれぞれの日付を変数
$day1
$day2
に格納
$interval = $day1->diff($day2);
- 変数
$day1
と$day2
をdiff
で比較 diff
の結果(日付の差)を変数$interval
に格納
echo $interval->format(‘%a 日’);
- 日付の差を
echo
で出力 format
で%a
とすると、日付の差が表示される
formatの’%a’とは
DateInterval::format
と言われるもので、間隔をフォーマットします。よく分かりませんね。
%
に続けて任意のフォーマット文字を繋げて使うことで、日にちや時間など、任意のフォーマットを返してくれます。
diff
を使った日付の差だと、a
を指定することで実際の日付の差をフォーマットしてくれます。
formatパラメータ一覧
%a
の他にも様々なパラメータがあります。
format文字 | 説明 | 例 |
---|---|---|
a | diff()ので使った場合は総日数、それ以外は(unknown) | 136 |
Y | 年、数値、先頭に 0 を含む 2 桁 | 01,10 |
y | 年、数値 | 1,10 |
M | 月、数値、先頭に 0 を含む 2 桁 | 01,12 |
m | 月、数値 | 1,12 |
D | 日、数値、先頭に 0 を含む 2 桁 | 01,10 |
d | 日、数値 | 1,10 |
H | 時間、数値、先頭に 0 を含む 2 桁 | 01,23 |
h | 時間、数値 | 1,23 |
I | 分、数値、先頭に 0 を含む 2 桁 | 01,59 |
i | 分、数値 | 1,59 |
S | 秒、数値、先頭に 0 を含む 2 桁 | 01,59 |
s | 秒、数値 | 1,59 |
R | 正の値には '+'、負の値には '-'を付ける | +,- |
r | 正の値は空文字、負の値には '-'を付ける | - |
分を返すなら%I
で、年なら%Y
とすればいいんですね。
DateTime
クラスを使いこなし、日付や時間の比較も自由自在に使いこなしましょう。