JavaScriptを利用したWebアプリケーション開発において、日付や時間の比較は非常に頻繁に発生する処理の一つです。
イベントの予約システムや期限切れの判定、あるいはデータの並べ替えなど、正確な日付比較が求められるシーンは多岐にわたります。
しかし、JavaScriptのDateオブジェクトは参照型であるため、単純な比較演算子だけでは意図しない挙動を示すことがあります。
本記事では、標準的なDateオブジェクトから最新のTemporal API、さらにはライブラリを活用した手法まで、実用的なコード例を交えて詳しく紹介します。
Dateオブジェクトを用いた基本的な比較方法
JavaScriptで日付を扱う際の基本となるのが、標準のDateオブジェクトです。
このオブジェクトを使用して日付の前後を判定する場合、基本的には比較演算子(<, >, <=, >=)を使用します。
比較演算子を使用すると、内部的にDateオブジェクトがミリ秒単位のタイムスタンプ(数値)に変換されるため、直感的な比較が可能になります。
getTime()メソッドによる数値変換
より明示的に比較を行いたい場合は、getTime()メソッドを使用してエポックタイム(1970年1月1日からのミリ秒数)を取得するのが確実です。
数値を比較することになるため、エラーが発生しにくく、計算ロジックとしても非常に安定します。
const dateA = new Date('2026-05-01T10:00:00');
const dateB = new Date('2026-05-01T15:00:00');
// getTime()を使ってミリ秒で比較
if (dateA.getTime() < dateB.getTime()) {
console.log('dateAはdateBより前の時刻です。');
}
dateAはdateBより前の時刻です。
比較演算子を直接使用する場合
Dateオブジェクト同士を直接比較演算子で結ぶことも可能です。
JavaScriptのエンジンは、比較演算子が使われた際に自動的にvalueOf()を呼び出し、数値を返します。
const start = new Date('2026-01-01');
const end = new Date('2026-12-31');
if (end > start) {
console.log('終了日は開始日より後です。');
}
終了日は開始日より後です。
日付の「一致」判定における注意点
日付の比較で最も多くのエンジニアが陥る罠が、「等価性(== や ===)の判定」です。
数値や文字列とは異なり、Dateオブジェクトは「オブジェクト」であるため、内容が同じでもインスタンスが異なれば偽(false)と判定されます。
なぜ「===」では判定できないのか
厳密等価演算子(===)は、メモリ上の参照先が同じであるかどうかをチェックします。
そのため、全く同じ日時を指していても、別々に生成されたオブジェクト同士は一致しません。
const d1 = new Date('2026-08-15');
const d2 = new Date('2026-08-15');
console.log(d1 === d2); // falseになる
false
正しい一致判定の書き方
日付が同じかどうかを正しく判定するためには、やはりタイムスタンプに変換して比較する必要があります。
以下のコードのように、getTime()やNumber()関数、あるいは単一のプラス記号(+)を用いて数値化します。
const d1 = new Date('2026-08-15');
const d2 = new Date('2026-08-15');
// getTime()で比較
const isEqual = d1.getTime() === d2.getTime();
console.log(isEqual); // trueになる
true
時刻を除外して「年月日」のみを比較する方法
実務では、具体的な時間(時分秒)は無視して、「同じ日かどうか」だけを判定したいケースが多くあります。
標準のDateオブジェクトには「日付のみ」を保持する型がないため、工夫が必要です。
時刻をゼロにリセットする
最も一般的な方法は、比較したい両方のオブジェクトの時刻部分をsetHours(0, 0, 0, 0)でリセットすることです。
const date1 = new Date('2026-10-10T15:30:00');
const date2 = new Date('2026-10-10T09:00:00');
// 時刻を00:00:00.000に合わせる
date1.setHours(0, 0, 0, 0);
date2.setHours(0, 0, 0, 0);
if (date1.getTime() === date2.getTime()) {
console.log('同じ日付です。');
}
同じ日付です。
toDateString()を利用した簡便な比較
厳密なパフォーマンスを求められない場合は、toDateString()メソッドで「年月日」のみの文字列に変換して比較する方法もあります。
このメソッドは “Fri May 01 2026” のような形式を返すため、日付部分のみを抽出するのに便利です。
const d1 = new Date('2026-05-01T12:00:00');
const d2 = new Date('2026-05-01T18:00:00');
if (d1.toDateString() === d2.toDateString()) {
console.log('日付部分は一致しています。');
}
日付部分は一致しています。
最新のTemporal APIによる次世代の日付比較
JavaScriptの新しい標準仕様として導入されたTemporal APIは、従来のDateオブジェクトが抱えていた多くの問題を解決します。
Temporal APIを使用すると、タイムゾーンや時刻の影響を受けずに、純粋な「日付」としての比較が驚くほど簡単になります。
Temporal.PlainDateの活用
Temporal.PlainDateを使用すれば、時刻情報を持たない日付オブジェクトを作成できます。
比較には専用のcompare関数が用意されており、これを使うことで安全にソートや前後判定が行えます。
const date1 = Temporal.PlainDate.from('2026-03-01');
const date2 = Temporal.PlainDate.from('2026-04-01');
const result = Temporal.PlainDate.compare(date1, date2);
if (result < 0) {
console.log('date1はdate2より前です。');
} else if (result > 0) {
console.log('date1はdate2より後です。');
} else {
console.log('二つの日付は同じです。');
}
date1はdate2より前です。
このように、戻り値が数値(-1, 0, 1)で返されるため、Array.prototype.sort()のコールバック関数としてもそのまま利用できるのが大きな利点です。
比較手法のまとめと選択基準
状況に応じて最適な比較方法は異なります。
以下の表を参考に、プロジェクトに最適な手法を選択してください。
| 手法 | メリット | デメリット |
|---|---|---|
| getTime() / valueOf() | 標準的で高速。等価判定も可能。 | コードが少し長くなる。 |
| 比較演算子 (<, >) | 直感的で簡潔に書ける。 | 一致判定 (===) には使えない。 |
| Temporal API | モダンで安全。日付のみの比較が容易。 | 古い環境ではポリフィルが必要。 |
| 外部ライブラリ (date-fns等) | 関数の名前がわかりやすく多機能。 | ライブラリの導入コストがかかる。 |
応用:日付範囲のチェックと配列のソート
日付比較の知識を応用して、実務でよく使われるロジックを実装してみましょう。
特定の日付が範囲内にあるか判定する
「開始日 <= 判定対象 <= 終了日」という条件式を記述します。
この際も、タイムスタンプ形式で比較を行うのが最も安全です。
const target = new Date('2026-06-15');
const start = new Date('2026-06-01');
const end = new Date('2026-06-30');
const isWithinRange = target >= start && target <= end;
console.log(`範囲内か:${isWithinRange}`);
範囲内か:true
日付を含む配列をソートする
複数のデータがある場合、日付順に並べ替える処理は頻繁に登場します。
sortメソッドの中で、Dateオブジェクト同士を引き算することで、昇順または降順のソートが可能です。
const events = [
{ name: 'イベントA', date: new Date('2026-12-01') },
{ name: 'イベントB', date: new Date('2026-10-01') },
{ name: 'イベントC', date: new Date('2026-11-01') }
];
// 昇順にソート
events.sort((a, b) => a.date - b.date);
events.forEach(e => console.log(`${e.name}: ${e.date.toLocaleDateString()}`));
イベントB: 2026/10/1
イベントC: 2026/11/1
イベントA: 2026/12/1
まとめ
JavaScriptでの日付比較は、一見シンプルに見えて奥が深いテーマです。
標準的なDateオブジェクトを使用する場合は、「等価判定には===を使わず、getTime()で数値化する」という鉄則を忘れないようにしましょう。
また、今後の開発においては、より堅牢な設計が可能なTemporal APIの採用も積極的に検討すべきです。
日付比較のミスはバグに直結しやすいため、適切なメソッド選びと入念なテストを心がけてください。
本記事で紹介したテクニックを活用し、正確でメンテナンス性の高い日付処理を実装していきましょう。
