PHPで日付を比較するには、DateTimeクラスやDateTimeImmutableクラス、strtotime()関数などを使用します。
例えば、「指定した日付が今日より前か」「2つの日付が同じか」「現在日時が有効期限内か」「予約日が受付期間に含まれているか」といった判定を実装できます。
ただし、PHPで日付を比較する際は、日付のフォーマットや時刻、タイムゾーン、存在しない日付の扱いに注意が必要です。
これらを正しく理解していないと、意図しない判定結果になったり、期限切れのデータを有効と判定したりする可能性があります。
この記事では、PHPで日付を比較する基本的な方法から、日付の範囲判定や差分計算、実務で役立つ実装例、比較時の注意点まで詳しく解説します。
PHPで日付を比較する主な方法
PHPで日付を比較する方法には、主に以下の4つがあります。
| 比較方法 | 特徴 | 主な用途 |
|---|---|---|
| DateTime | 日付や時刻をオブジェクトとして比較できる | 一般的な日時比較 |
| DateTimeImmutable | 元の日時を変更せずに比較できる | 保守性を重視する日付処理 |
| strtotime() | 日付文字列をUnixタイムスタンプに変換できる | 簡単な日付比較 |
| 文字列比較 | 形式が統一されていれば直接比較できる | Y-m-d形式の日付比較 |
それぞれの方法には特徴がありますが、基本的にはDateTimeImmutableクラスを使用する方法がおすすめです。
DateTimeImmutableは、日時を変更するメソッドを呼び出しても元のオブジェクトが変更されないため、意図しない値の書き換えを防ぎやすいというメリットがあります。
また、日付の加算・減算やタイムゾーンの指定、日付の差分計算にも対応しているため、さまざまな場面で活用できます。
PHPのDateTimeクラスで日付を比較する方法
DateTimeは、PHPで日付や時刻を扱うための標準クラスです。
日付文字列からDateTimeオブジェクトを生成することで、比較演算子を使用して日時の前後関係や一致を判定できます。
2つの日付の前後関係を比較する
PHPでは、DateTimeオブジェクト同士を比較演算子で直接比較できます。
<?php
$date1 = new DateTime('2026-11-10');
$date2 = new DateTime('2026-11-15');
if ($date1 < $date2) {
echo 'date1はdate2より前の日付です';
} elseif ($date1 > $date2) {
echo 'date1はdate2より後の日付です';
} else {
echo '同じ日時です';
}
実行結果
date1はdate2より前の日付です
このコードでは、2026年11月10日と2026年11月15日を比較しています。
$date1の方が過去の日付であるため、最初の条件が成立します。
日付の比較で使用する主な比較演算子は以下のとおりです。
| 演算子 | 意味 |
|---|---|
< | 左側の日時が右側より前 |
> | 左側の日時が右側より後 |
<= | 左側の日時が右側以前 |
>= | 左側の日時が右側以降 |
== | 同じ日時 |
!= | 異なる日時 |
これらの演算子を使用することで、数値を比較する場合と同じような書き方で日時を判定できます。
2つの日付が同じか判定する
2つの日時が一致しているかを確認する場合は、==演算子を使用します。
<?php
$date1 = new DateTime('2026-11-10');
$date2 = new DateTime('2026-11-10');
if ($date1 == $date2) {
echo '同じ日時です';
} else {
echo '異なる日時です';
}
実行結果
同じ日時です
DateTimeオブジェクトが別々に生成されていても、表している日時が同じであれば==による比較ではtrueになります。
ただし、==と===では判定する内容が異なります。
<?php
$date1 = new DateTime('2026-11-10');
$date2 = new DateTime('2026-11-10');
var_dump($date1 == $date2);
var_dump($date1 === $date2);
実行結果
bool(true)
bool(false)
==は日時オブジェクトの値に基づいて比較します。
一方、===は同じオブジェクトインスタンスを参照しているかを判定します。
そのため、日時の一致を確認したい場合は、基本的に==を使用します。
時刻を含めて日付を比較する
DateTimeでは、年月日だけでなく時刻を含めた比較も可能です。
<?php
$date1 = new DateTime('2026-11-10 09:00:00');
$date2 = new DateTime('2026-11-10 18:00:00');
if ($date1 < $date2) {
echo 'date1の方が早い日時です';
} else {
echo 'date1はdate2以降の日時です';
}
実行結果
date1の方が早い日時です
この例では、どちらも2026年11月10日ですが、時刻が異なります。
そのため、午前9時の方が午後6時より前と判定されます。
日付が同じでも、時刻が異なれば比較結果も変わる点に注意してください。
年月日だけを比較したい場合は、時刻を除外して判定する必要があります。
PHPのDateTimeImmutableクラスで日付を比較する方法
DateTimeImmutableは、DateTimeと同じように日付や時刻を扱えるクラスです。
両者の大きな違いは、日時を変更するメソッドを実行した際の動作です。
DateTimeでは元のオブジェクトが変更されるのに対し、DateTimeImmutableでは新しいオブジェクトが返されます。
DateTimeImmutableを使用した基本的な比較
DateTimeImmutableでも、比較演算子によって日時を直接比較できます。
<?php
$date1 = new DateTimeImmutable('2026-11-10');
$date2 = new DateTimeImmutable('2026-11-15');
if ($date1 < $date2) {
echo '指定した日付は比較対象より前です';
}
実行結果
指定した日付は比較対象より前です
基本的な比較方法はDateTimeと同じです。
<や>などの演算子を使用して、日時の前後関係を判定できます。
DateTimeとDateTimeImmutableの違い
DateTimeとDateTimeImmutableの違いを、具体的なコードで確認してみましょう。
まず、DateTimeの場合です。
<?php
$date = new DateTime('2026-11-10');
$date->modify('+1 day');
echo $date->format('Y-m-d');
実行結果
2026-11-11
DateTimeでは、modify()メソッドを実行すると元のオブジェクトの日時が変更されます。
一方、DateTimeImmutableでは次のようになります。
<?php
$date = new DateTimeImmutable('2026-11-10');
$newDate = $date->modify('+1 day');
echo $date->format('Y-m-d');
echo "\n";
echo $newDate->format('Y-m-d');
実行結果
2026-11-10
2026-11-11
元の$dateは2026年11月10日のままで、新しい日付が$newDateに格納されます。
予約日や有効期限など、複数の処理で同じ日時を使用する場合は、途中で値が変更されると不具合につながる可能性があります。
そのため、特別な理由がなければDateTimeImmutableの使用を検討するとよいでしょう。
PHPのstrtotime関数で日付を比較する方法
strtotime()は、日付や時刻を表す文字列をUnixタイムスタンプに変換する関数です。
Unixタイムスタンプとは、1970年1月1日00時00分00秒(UTC)からの経過秒数を表す数値です。
日時を数値に変換することで、大小関係を比較できます。
strtotime関数の基本的な使い方
<?php
$date1 = strtotime('2026-11-10');
$date2 = strtotime('2026-11-15');
if ($date1 === false || $date2 === false) {
echo '日付の変換に失敗しました';
} elseif ($date1 < $date2) {
echo 'date1の方が過去の日付です';
} elseif ($date1 > $date2) {
echo 'date1の方が未来の日付です';
} else {
echo '同じ日時です';
}
実行結果
date1の方が過去の日付です
strtotime()で正常に変換できた場合、戻り値は整数になります。
そのため、数値の大小比較と同じ方法で日時を比較できます。
ただし、strtotime()は変換に失敗するとfalseを返します。
戻り値を確認せずに比較すると、想定外の判定につながる可能性があるため注意してください。
また、strtotime()は日付文字列を柔軟に解釈する関数です。
ユーザーが入力した日付の形式や妥当性を厳密に検証する用途には適していません。
今日の日付と指定した日付を比較する
strtotime()を使用すれば、今日の日付と指定した日付も比較できます。
<?php
date_default_timezone_set('Asia/Tokyo');
$today = strtotime('today');
$target = strtotime('2026-11-15');
if ($target === false || $today === false) {
echo '日付の取得に失敗しました';
} elseif ($target > $today) {
echo '指定した日付は今日より後です';
} elseif ($target < $today) {
echo '指定した日付は今日より前です';
} else {
echo '指定した日付は今日です';
}
strtotime('today')は、デフォルトタイムゾーンにおける今日の午前0時を表すタイムスタンプを取得します。
そのため、指定した日付が今日より前か後かを判定できます。
ただし、この方法は日付単位での比較を想定しています。
現在の時刻まで含めて比較する場合は、time()やDateTimeImmutableを使用するとよいでしょう。
現在時刻と指定した日時を比較する
現在時刻をUnixタイムスタンプで取得するには、time()を使用します。
<?php
date_default_timezone_set('Asia/Tokyo');
$now = time();
$deadline = strtotime('2026-11-15 18:00:00');
if ($deadline === false) {
echo '日時の変換に失敗しました';
} elseif ($now < $deadline) {
echo '期限前です';
} else {
echo '期限に達しています';
}
このコードでは、現在時刻と2026年11月15日18時を比較しています。
time()は現在のUnixタイムスタンプを返すため、秒単位で期限を判定できます。
なお、strtotime()にタイムゾーンの指定がない日時文字列を渡した場合は、PHPのデフォルトタイムゾーンに基づいて解釈されます。
サーバー環境によって判定結果が変わらないように、タイムゾーンを明示することが重要です。
また、Unixタイムスタンプには実行環境の整数サイズによる制限があります。
特に32ビット環境では表現可能な日時の範囲が制限されるため、広い年月日を扱う場合は注意が必要です。
PHPで日付文字列を直接比較する方法
PHPでは、一定の条件を満たしていれば、日付文字列を直接比較することも可能です。
例えば、Y-m-d形式で統一された有効な日付であれば、文字列の辞書順と日付の前後関係が一致します。
Y-m-d形式の日付を比較する
<?php
$date1 = '2026-11-10';
$date2 = '2026-11-15';
if (strcmp($date1, $date2) < 0) {
echo 'date1の方が過去の日付です';
} elseif (strcmp($date1, $date2) > 0) {
echo 'date1の方が未来の日付です';
} else {
echo '同じ日付です';
}
実行結果
date1の方が過去の日付です
strcmp()は、2つの文字列を比較する関数です。
戻り値には次のような意味があります。
| 戻り値 | 意味 |
|---|---|
| 0より小さい | 1つ目の文字列が辞書順で前 |
| 0 | 2つの文字列が一致 |
| 0より大きい | 1つ目の文字列が辞書順で後 |
Y-m-d形式では、年・月・日が大きい単位から順番に並んでいます。
さらに、月と日が2桁でゼロ埋めされているため、同じ形式の有効な日付同士であれば辞書順による比較が可能です。
日付文字列を比較する際の注意点
日付文字列を直接比較する場合は、フォーマットを統一する必要があります。
例えば、次のような形式では注意が必要です。
<?php
$date1 = '2026-2-10';
$date2 = '2026-11-15';
この例では、月がゼロ埋めされていません。
そのため、辞書順と実際の日付の順番が一致しない可能性があります。
また、次のように区切り文字が異なる場合も、文字列比較には適していません。
<?php
$date1 = '2026/11/10';
$date2 = '2026-11-15';
文字列比較を使用する場合は、以下の条件を満たすことが重要です。
Y-m-dなどの固定形式に統一する- 年・月・日の桁数を統一する
- 月や日をゼロ埋めする
- 比較対象のタイムゾーンを統一する
- 存在する日付であることを事前に確認する
また、PHPの文字列に対して単純に<や>を使用すると、数値として解釈できる文字列では数値比較が行われる場合があります。
そのため、文字列の辞書順を明示的に比較したい場合は、strcmp()を使用すると意図が明確になります。
ただし、一般的なWebアプリケーションでは、日付文字列をDateTimeImmutableに変換して比較する方が柔軟に対応できます。
PHPで日付だけを比較する方法
日付比較では、時刻を含めずに年月日だけを比較したい場合があります。
例えば、会員の登録日やイベントの開催日、商品の発売日などを判定するケースです。
このような場合は、時刻の違いを除外して比較する必要があります。
formatメソッドで年月日だけを比較する
format()メソッドを使用すると、日時オブジェクトから年月日を文字列として取得できます。
<?php
$timezone = new DateTimeZone('Asia/Tokyo');
$date1 = new DateTimeImmutable(
'2026-11-10 09:00:00',
$timezone
);
$date2 = new DateTimeImmutable(
'2026-11-10 18:00:00',
$timezone
);
if ($date1->format('Y-m-d') === $date2->format('Y-m-d')) {
echo '同じ日付です';
}
実行結果
同じ日付です
このコードでは、時刻が異なっていても年月日が一致するため、同じ日付と判定されます。
format('Y-m-d')で取得できる値は、次のような文字列です。
2026-11-10
文字列同士の一致判定であるため、===を使用できます。
なお、異なるタイムゾーンの日時を比較する場合は、あらかじめ同じタイムゾーンに変換する必要があります。
setTimeメソッドで時刻を統一する
setTime()メソッドを使用すると、日時オブジェクトの時刻部分を指定した値に設定できます。
日付だけを比較する場合は、両方の時刻を午前0時に統一する方法もあります。
<?php
$timezone = new DateTimeZone('Asia/Tokyo');
$date1 = new DateTimeImmutable(
'2026-11-10 09:00:00',
$timezone
);
$date2 = new DateTimeImmutable(
'2026-11-10 18:00:00',
$timezone
);
$date1 = $date1->setTime(0, 0, 0, 0);
$date2 = $date2->setTime(0, 0, 0, 0);
if ($date1 == $date2) {
echo '同じ日付です';
}
実行結果
同じ日付です
このコードでは、両方の日時を2026年11月10日00時00分00秒に統一しています。
そのため、時刻の違いを除外して比較できます。
ただし、夏時間の切り替えがある地域では、午前0時の扱いが特殊になる場合があります。
年月日の一致だけを判定する場合は、比較するタイムゾーンを統一したうえで、format('Y-m-d')を使用する方法がわかりやすいでしょう。
PHPで今日・昨日・明日と日付を比較する方法
PHPでは、現在の日付を基準にして、指定した日付が過去か未来かを判定できます。
ここでは、DateTimeImmutableを使用した方法を紹介します。
指定した日付が今日より前か判定する
指定した日付が今日より前かを判定するには、今日の日付を取得して比較します。
<?php
$timezone = new DateTimeZone('Asia/Tokyo');
$today = new DateTimeImmutable('today', $timezone);
$target = new DateTimeImmutable('2026-11-01', $timezone);
if ($target < $today) {
echo '過去の日付です';
} else {
echo '今日または未来の日付です';
}
todayを指定すると、現在のタイムゾーンにおける今日の午前0時が取得されます。
そのため、日付単位の比較に利用できます。
指定した日付が今日以降か判定する
今日を含めた未来の日付を判定する場合は、>=演算子を使用します。
<?php
$timezone = new DateTimeZone('Asia/Tokyo');
$today = new DateTimeImmutable('today', $timezone);
$target = new DateTimeImmutable('2026-11-15', $timezone);
if ($target >= $today) {
echo '今日以降の日付です';
} else {
echo '今日より前の日付です';
}
このコードでは、今日と同じ日付も条件に含まれます。
一方、今日を含めずに未来の日付だけを判定する場合は、>を使用します。
現在時刻より未来か判定する
日時を比較する場合は、todayではなくnowを使用します。
<?php
$timezone = new DateTimeZone('Asia/Tokyo');
$now = new DateTimeImmutable('now', $timezone);
$target = new DateTimeImmutable(
'2026-12-01 12:00:00',
$timezone
);
if ($target > $now) {
echo '現在時刻より未来です';
} else {
echo '現在時刻以前です';
}
todayとnowの違いは以下のとおりです。
| 指定値 | 取得する日時 | 主な用途 |
|---|---|---|
today | 今日の午前0時 | 日付単位の比較 |
now | 現在の日時 | 時刻を含む比較 |
yesterday | 昨日の午前0時 | 昨日との比較 |
tomorrow | 明日の午前0時 | 明日との比較 |
例えば、イベントの開催日を比較する場合はtoday、申し込みの締め切り日時を比較する場合はnowが適しています。
PHPで日付が指定した期間内か判定する方法
Webアプリケーションでは、指定した日付が一定の範囲内に含まれているかを判定するケースがあります。
例えば、キャンペーン期間や予約受付期間、会員資格の有効期間などです。
開始日と終了日の範囲内か判定する
開始日と終了日を設定し、その範囲に対象の日付が含まれているかを確認します。
<?php
$timezone = new DateTimeZone('Asia/Tokyo');
$start = new DateTimeImmutable(
'2026-11-01',
$timezone
);
$end = new DateTimeImmutable(
'2026-11-30',
$timezone
);
$target = new DateTimeImmutable(
'2026-11-15',
$timezone
);
if ($target >= $start && $target <= $end) {
echo '指定した日付は期間内です';
} else {
echo '指定した日付は期間外です';
}
実行結果
指定した日付は期間内です
このコードでは、&&演算子を使用して2つの条件を組み合わせています。
$target >= $start && $target <= $end
それぞれの意味は以下のとおりです。
$target >= $start:対象の日付が開始日以降である$target <= $end:対象の日付が終了日以前である
両方の条件を満たした場合に、期間内と判定されます。
ただし、このコードは日付のみを扱い、いずれも午前0時として比較することを想定しています。
時刻を含む日時を比較する場合は、終了日の扱いに注意が必要です。
終了日を含めて日時を比較する
例えば、キャンペーン期間が2026年11月1日から11月30日までの場合を考えます。
終了日を次のように指定すると、意図しない結果になる可能性があります。
<?php
$end = new DateTimeImmutable('2026-11-30');
この場合、終了日時は2026年11月30日00時00分00秒として扱われます。
そのため、11月30日の昼や夜の日時は、終了日時より後と判定されます。
この問題を防ぐには、終了日の翌日を終了境界として、その日時より前かどうかを判定する方法がおすすめです。
<?php
$timezone = new DateTimeZone('Asia/Tokyo');
$start = new DateTimeImmutable(
'2026-11-01 00:00:00',
$timezone
);
$endExclusive = new DateTimeImmutable(
'2026-12-01 00:00:00',
$timezone
);
$target = new DateTimeImmutable(
'2026-11-30 23:59:59',
$timezone
);
if ($target >= $start && $target < $endExclusive) {
echo 'キャンペーン期間内です';
}
このコードでは、12月1日の午前0時を終了境界として設定しています。
<演算子を使用することで、終了境界そのものは含めず、それより前の日時を対象としています。
この方法なら、11月30日23時59分59秒だけでなく、マイクロ秒を含む日時にも対応できます。
期間判定では、以下のような条件が実務でもよく使用されます。
$target >= $start && $target < $endExclusive
開始日時を含み、終了日時を含まない区間を使用すると、期間の境界が重複する問題を防ぎやすくなります。
PHPで2つの日付の差を計算する方法
PHPでは、diff()メソッドを使用して2つの日付の差を計算できます。
例えば、指定した日付までの残り日数や、登録日からの経過日数を取得する場合に利用できます。
diffメソッドで日数の差を取得する
<?php
$date1 = new DateTimeImmutable('2026-11-10');
$date2 = new DateTimeImmutable('2026-11-15');
$interval = $date1->diff($date2);
echo $interval->days . '日';
実行結果
5日
diff()メソッドは、2つの日時の差を表すDateIntervalオブジェクトを返します。
主なプロパティは以下のとおりです。
| プロパティ | 内容 |
|---|---|
y | 年の差 |
m | 月の差 |
d | 日の差 |
h | 時間の差 |
i | 分の差 |
s | 秒の差 |
days | 合計日数 |
invert | 差分の方向 |
diff()で取得したDateIntervalでは、daysプロパティから合計日数を取得できます。
ただし、DateIntervalを直接生成した場合などは、daysがfalseになることがあります。
また、diff()はタイムゾーンや夏時間を考慮した差分を返します。
そのため、暦上の日数と実際の経過秒数を86,400で割った結果が、常に一致するとは限りません。
指定した日付が7日以内か判定する
例えば、基準日から7日以内の日付かを判定する場合は、次のように実装できます。
<?php
$timezone = new DateTimeZone('Asia/Tokyo');
$today = new DateTimeImmutable(
'2026-11-10',
$timezone
);
$target = new DateTimeImmutable(
'2026-11-15',
$timezone
);
$interval = $today->diff($target);
if (
$interval->invert === 0 &&
$interval->days <= 7
) {
echo '7日以内の日付です';
} else {
echo '7日以内ではありません';
}
実行結果
7日以内の日付です
このコードでは、invertプロパティも確認しています。
invertは、日時の差分の方向を表すプロパティです。
| 値 | 意味 |
|---|---|
0 | 対象日時が基準日時以降 |
1 | 対象日時が基準日時より前 |
今回のように「今後7日以内」を判定する場合は、過去の日付を除外する必要があります。
そのため、daysだけでなくinvertも確認しています。
なお、この例は日付単位での比較を想定しています。
厳密に168時間以内かどうかを判定する場合は、Unixタイムスタンプの差を使用する方法が適しています。
Unixタイムスタンプで経過時間を比較する
2つの日時の経過秒数を計算したい場合は、getTimestamp()を使用できます。
<?php
$timezone = new DateTimeZone('Asia/Tokyo');
$date1 = new DateTimeImmutable(
'2026-11-10 10:00:00',
$timezone
);
$date2 = new DateTimeImmutable(
'2026-11-12 10:00:00',
$timezone
);
$seconds = $date2->getTimestamp() - $date1->getTimestamp();
$hours = $seconds / 3600;
echo $hours . '時間';
実行結果
48時間
getTimestamp()は、日時をUnixタイムスタンプとして取得するメソッドです。
取得した数値同士を引き算することで、経過秒数を計算できます。
ただし、Unixタイムスタンプは秒単位の値であるため、マイクロ秒単位の精度が必要な場合は別途対応が必要です。
PHPで日付を比較する際の注意点
PHPで日付を比較する際は、入力形式やタイムゾーン、存在しない日付などに注意する必要があります。
ここでは、実務で特に重要なポイントを解説します。
存在しない日付が自動補正される場合がある
PHPでは、存在しない日付が自動的に補正される場合があります。
例えば、次のコードです。
<?php
$date = new DateTimeImmutable('2026-02-30');
echo $date->format('Y-m-d');
実行結果
2026-03-02
2026年2月30日は存在しません。
しかし、このような日付をPHPが補正して解釈する場合があります。
そのため、ユーザーが入力した日付をそのまま比較するだけでは不十分です。
入力された日付が実際に存在するかを事前に検証する必要があります。
checkdate関数で日付の妥当性を確認する
年月日が正しいかを確認するには、checkdate()関数を使用できます。
<?php
$year = 2026;
$month = 2;
$day = 30;
if (checkdate($month, $day, $year)) {
echo '有効な日付です';
} else {
echo '無効な日付です';
}
実行結果
無効な日付です
checkdate()は、指定した年月日がグレゴリオ暦上で有効かを判定する関数です。
引数の順番は以下のとおりです。
checkdate(月, 日, 年);
年・月・日の順番ではないため注意してください。
また、checkdate()は年月日の妥当性を確認する関数であり、時刻やタイムゾーンの検証には対応していません。
createFromFormatで日付の形式を厳密に検証する
入力形式が決まっている場合は、DateTimeImmutable::createFromFormat()を使用する方法がおすすめです。
例えば、Y-m-d形式の日付だけを受け付ける場合は、次のように実装できます。
<?php
function isValidDate(string $value): bool
{
$timezone = new DateTimeZone('Asia/Tokyo');
try {
$date = DateTimeImmutable::createFromFormat(
'!Y-m-d',
$value,
$timezone
);
} catch (ValueError $e) {
return false;
}
if ($date === false) {
return false;
}
$errors = DateTimeImmutable::getLastErrors();
if (
$errors !== false &&
(
$errors['warning_count'] > 0 ||
$errors['error_count'] > 0
)
) {
return false;
}
return $date->format('Y-m-d') === $value;
}
var_dump(isValidDate('2026-11-10'));
var_dump(isValidDate('2026-02-30'));
var_dump(isValidDate('2026-2-3'));
実行結果
bool(true)
bool(false)
bool(false)
このコードでは、次の項目を確認しています。
- 日付文字列を正常に解析できたか
- 解析時に警告やエラーが発生していないか
- 入力文字列と変換後の日付が完全に一致しているか
- NULLバイトなどによる
ValueErrorが発生していないか
createFromFormat()に指定している!Y-m-dの!は、指定されていない日時の要素を初期化するための書式指定子です。
これを指定しない場合、入力していない時刻部分に現在時刻が引き継がれることがあります。
また、PHP 8.2以降では、getLastErrors()は警告とエラーがない場合にfalseを返します。
それ以前のバージョンでは、警告やエラーがなくても配列が返されます。
上記のコードは、この違いも考慮しています。
なお、外部から受け取った日時文字列をDateTimeImmutableのコンストラクタに直接渡す場合も、解析失敗時の例外処理を検討してください。
PHP 8.3以降では、解析できない日時文字列に対してDateMalformedStringExceptionが発生します。
PHP 8.2以前では、同様のケースでExceptionが使用されていました。
タイムゾーンの違いに注意する
PHPの日付比較では、タイムゾーンの違いにも注意が必要です。
例えば、日本時間とUTCで異なる時刻を指定していても、実際には同じ瞬間を表している場合があります。
<?php
$date1 = new DateTimeImmutable(
'2026-11-10 12:00:00',
new DateTimeZone('Asia/Tokyo')
);
$date2 = new DateTimeImmutable(
'2026-11-10 03:00:00',
new DateTimeZone('UTC')
);
var_dump($date1 == $date2);
実行結果
bool(true)
日本時間の12時は、UTCでは同日の3時です。
そのため、日時を表す文字列が異なっていても、同じ瞬間を表しているためtrueになります。
ただし、年月日だけを比較する場合は注意が必要です。
日本時間では11月11日でも、UTCでは11月10日というケースがあります。
そのため、日時の前後関係を比較する場合と、特定のタイムゾーンにおける日付を比較する場合は区別する必要があります。
setTimezoneメソッドでタイムゾーンを統一する
異なるタイムゾーンの日時を、日本時間の日付として比較したい場合は、setTimezone()を使用します。
<?php
$utc = new DateTimeZone('UTC');
$tokyo = new DateTimeZone('Asia/Tokyo');
$date1 = new DateTimeImmutable(
'2026-11-10 16:00:00',
$utc
);
$date2 = new DateTimeImmutable(
'2026-11-11 08:00:00',
$tokyo
);
$date1Tokyo = $date1->setTimezone($tokyo);
if (
$date1Tokyo->format('Y-m-d') ===
$date2->format('Y-m-d')
) {
echo '日本時間では同じ日付です';
}
実行結果
日本時間では同じ日付です
このコードでは、UTCで表された日時を日本時間に変換してから比較しています。
そのため、日本時間における年月日の一致を正しく判定できます。
date_default_timezone_setでタイムゾーンを設定する
PHPのデフォルトタイムゾーンは、date_default_timezone_set()で設定できます。
<?php
date_default_timezone_set('Asia/Tokyo');
$now = new DateTimeImmutable();
echo $now->format('Y-m-d H:i:s');
Asia/Tokyoを指定すると、日本時間を基準に日時を扱えます。
ただし、アプリケーション全体のタイムゾーン設定を変更したくない場合は、オブジェクトを生成する際にDateTimeZoneを指定する方法が適しています。
<?php
$timezone = new DateTimeZone('Asia/Tokyo');
$now = new DateTimeImmutable('now', $timezone);
Webアプリケーションでは、開発環境と本番環境でタイムゾーンの設定が異なる場合があります。
そのため、日時の解釈に影響するタイムゾーンは、明示的に指定するとよいでしょう。
うるう年を考慮する
日付比較では、うるう年にも注意が必要です。
うるう年には2月29日が存在しますが、通常の年には存在しません。
例えば、2028年はうるう年です。
<?php
var_dump(checkdate(2, 29, 2028));
var_dump(checkdate(2, 29, 2029));
実行結果
bool(true)
bool(false)
DateTimeImmutableやcheckdate()を使用すれば、うるう年を考慮した日付処理ができます。
なお、日付の差を計算する場合に、1年を常に365日として扱うことは避けましょう。
実際の日付を基準とした計算には、diff()やDateIntervalを使用する方法が適しています。
夏時間による時刻の変化に注意する
日本では現在、夏時間が採用されていません。
しかし、海外のタイムゾーンでは、夏時間によって時計が1時間進んだり戻ったりすることがあります。
そのため、暦上の1日が必ずしも24時間になるとは限りません。
例えば、夏時間への切り替えがある地域では、翌日の同じ時刻までの経過時間が23時間になる場合があります。
日付単位の計算と、厳密な経過時間の計算は区別することが重要です。
暦上の日付差を計算する場合はDateIntervalを使用し、経過秒数が必要な場合はUnixタイムスタンプなどを利用するとよいでしょう。
期間の開始日と終了日の境界条件に注意する
日付の範囲判定では、開始日や終了日を含めるかどうかを明確にする必要があります。
例えば、次の2つの条件は意味が異なります。
$target <= $deadline;
$target < $deadline;
<=は、期限と同じ日時も含めます。
一方、<は期限と同じ日時を含めません。
そのため、「30日以内」「月末まで」「終了日時より前」などの条件を実装する場合は、仕様に合わせて比較演算子を選択する必要があります。
特に、有効期限や予約受付期限では、境界条件の違いが不具合につながることがあるため注意してください。
PHPの日付比較を実務で活用する方法
ここからは、WebサイトやWebアプリケーションで使用することが多い日付比較の実装例を紹介します。
会員登録から30日以内か判定する
例えば、会員登録から30日以内のユーザーに特典を付与する場合です。
<?php
$timezone = new DateTimeZone('Asia/Tokyo');
$registeredAt = new DateTimeImmutable(
'2026-11-01 10:00:00',
$timezone
);
$now = new DateTimeImmutable('now', $timezone);
$deadline = $registeredAt->add(
new DateInterval('P30D')
);
if ($now >= $registeredAt && $now <= $deadline) {
echo '登録から30日以内です';
} else {
echo '対象期間外です';
}
このコードでは、登録日時から30暦日後の同じ時刻までを対象としています。
P30Dは、30日間を表すDateIntervalの指定です。
また、<=を使用しているため、登録からちょうど30日後の日時も対象に含まれます。
なお、登録から30日後の日時を含めない場合は、<を使用します。
また、登録日を1日目と数える場合や、厳密に720時間以内を判定する場合は、計算方法を変更する必要があります。
予約可能日か判定する
予約システムでは、指定した日付が予約可能な範囲に含まれているかを判定する場合があります。
例えば、今日から30日後まで予約できる場合です。
<?php
$timezone = new DateTimeZone('Asia/Tokyo');
$today = new DateTimeImmutable('today', $timezone);
$limit = $today->add(
new DateInterval('P30D')
);
$reservationDate = new DateTimeImmutable(
'2026-11-20',
$timezone
);
if (
$reservationDate >= $today &&
$reservationDate <= $limit
) {
echo '予約可能な日付です';
} else {
echo '予約できない日付です';
}
このコードでは、今日から30日後までを予約可能な日付として判定しています。
ただし、実際の予約システムでは、定休日や営業時間、予約枠の空き状況なども確認する必要があります。
日付比較は、予約可能かどうかを判定するための基本処理として利用できます。
クーポンの有効期限を判定する
クーポンの有効期限を判定する場合は、現在日時と有効期限を比較します。
例えば、2026年11月30日まで有効なクーポンの場合です。
<?php
$timezone = new DateTimeZone('Asia/Tokyo');
$now = new DateTimeImmutable('now', $timezone);
$endExclusive = new DateTimeImmutable(
'2026-12-01 00:00:00',
$timezone
);
if ($now < $endExclusive) {
echo 'クーポンは有効です';
} else {
echo 'クーポンの有効期限が切れています';
}
このコードでは、2026年12月1日00時00分00秒より前を有効期間としています。
そのため、11月30日の終了までクーポンを有効として扱えます。
終了日時を23:59:59に固定する方法と異なり、マイクロ秒を含む日時でも判定しやすい点がメリットです。
なお、この例は終了日時のみを確認しています。
利用開始日時も設定されている場合は、開始日時以降であることも条件に追加してください。
記事の公開日時を判定する
ブログやニュースサイトでは、公開予定日時になったら記事を表示する処理が必要になる場合があります。
<?php
$timezone = new DateTimeZone('Asia/Tokyo');
$now = new DateTimeImmutable('now', $timezone);
$publishAt = new DateTimeImmutable(
'2026-11-15 09:00:00',
$timezone
);
if ($now >= $publishAt) {
echo '記事を公開します';
} else {
echo '公開予定の記事です';
}
このコードでは、現在日時が公開予定日時に達しているかを判定しています。
>=を使用することで、公開予定日時と同じ時刻になった場合も条件が成立します。
ただし、このコード自体が指定した時刻に自動実行されるわけではありません。
実際の自動公開機能を実装する場合は、ページ表示時の公開可否判定や、定期実行処理などと組み合わせる必要があります。
PHPで日付を比較するときによくある質問
PHPで日付を比較するならDateTimeとstrtotimeのどちらがおすすめですか?
一般的には、DateTimeImmutableがおすすめです。
strtotime()は日付文字列をUnixタイムスタンプに変換できるため、簡単な日時比較には便利です。
一方、DateTimeImmutableは、タイムゾーンの指定や日付の加算・減算、差分計算などにも対応しています。
また、日時を変更するメソッドを使用しても元のオブジェクトが変更されないため、保守性を重視する処理にも適しています。
そのため、一般的なWebアプリケーションではDateTimeImmutableを使用するとよいでしょう。
PHPで日付を比較するときにフォーマットを統一する必要はありますか?
日付文字列を直接比較する場合は、フォーマットを統一する必要があります。
例えば、Y-m-d形式で統一された有効な日付であれば、辞書順による比較が可能です。
一方、DateTimeImmutableオブジェクトに変換して比較する場合は、元の文字列の表示形式が異なっていても、正しく解析された日時同士で比較できます。
ただし、外部から受け取った文字列については、入力形式や日付の妥当性を事前に確認することが重要です。
PHPで日付が同じかどうかを判定するにはどうすればよいですか?
日時が完全に一致するかを判定する場合は、DateTimeImmutableオブジェクト同士を==で比較します。
$date1 == $date2
年月日だけが一致するかを判定する場合は、format('Y-m-d')で文字列に変換して比較するとわかりやすいでしょう。
$date1->format('Y-m-d') === $date2->format('Y-m-d')
ただし、年月日を比較する場合は、同じタイムゾーンを使用する必要があります。
PHPで日付が今日以降かを判定するにはどうすればよいですか?
DateTimeImmutableを使用し、今日の午前0時以降かを判定します。
<?php
$timezone = new DateTimeZone('Asia/Tokyo');
$today = new DateTimeImmutable('today', $timezone);
$target = new DateTimeImmutable(
'2026-11-15',
$timezone
);
if ($target >= $today) {
echo '今日以降の日付です';
}
>=を使用することで、今日を含めた比較ができます。
一方、現在時刻より未来かどうかを判定する場合は、todayではなくnowを使用してください。
PHPで日付を比較して何日後かを取得するにはどうすればよいですか?
DateTimeImmutableのdiff()メソッドを使用すると、2つの日付の差を取得できます。
<?php
$date1 = new DateTimeImmutable('2026-11-10');
$date2 = new DateTimeImmutable('2026-11-20');
$interval = $date1->diff($date2);
echo $interval->days . '日後';
実行結果
10日後
この例では、$date2が$date1より後の日付であるため、10日後と表示できます。
ただし、daysは日数差の方向を表しません。
前後関係も含めて判定する場合は、invertプロパティを確認する必要があります。
まとめ
PHPでは、DateTimeやDateTimeImmutable、strtotime()などを使用して日付を比較できます。
それぞれに特徴がありますが、一般的なWebアプリケーションでは、DateTimeImmutableを使用する方法がおすすめです。
PHPで日付を比較する際は、以下のポイントを押さえておきましょう。
- 日時の前後関係は
<や>などの比較演算子で判定する - 日時の一致判定には
==を使用する - 年月日だけを比較する場合は、時刻を除外する
- 日付の差を計算する場合は
diff()を使用する - 期間判定では開始日時と終了日時の境界条件を明確にする
- 入力された日付の妥当性を確認する
- タイムゾーンやうるう年、夏時間の影響を考慮する
- 暦上の日数と実際の経過時間を区別する
特に重要なのは、「日付だけを比較するのか」「時刻まで含めて比較するのか」を明確にすることです。
例えば、イベントの開催日を比較する場合は年月日だけの判定で十分ですが、クーポンの有効期限や記事の公開日時を判定する場合は、時刻まで含めた比較が必要になります。
また、ユーザーが入力した日付を扱う場合は、checkdate()やDateTimeImmutable::createFromFormat()によって、日付の形式や妥当性を検証することも重要です。
PHPの日付比較を正しく理解し、用途に応じた方法を使い分けることで、予約システムや会員管理、キャンペーン期間の判定など、さまざまな機能を正確に実装できます。
実務で繰り返し利用する場合は、日付の妥当性チェックや期間内判定を共通関数としてまとめておくと、コードの重複を減らし、保守性も高められるでしょう。
以上、PHPで日付を比較する方法や判定時の注意点についてでした。
最後までお読みいただき、ありがとうございました。










