「Date 判定」とは何を見分けたいのか
ここでいう「Date 判定」は、その値が「本物の Date オブジェクトかどうか」を見分けることです。
業務では「日付を表す値」がたくさん出てきますが、その正体はだいたい次のどれかです。
Dateオブジェクト(new Date())- 日付文字列(
"2025-02-05"など) - タイムスタンプ(
1738742400000のような数値) nullやundefined(未設定)- よく分からない値(バグで混入したもの)
「これは Date だ」と思って value.getTime() を呼んだら、実は文字列で落ちる――
このパターンを防ぐために、「Date かどうか」をきちんと判定するユーティリティが必要になります。
typeof では Date を判定できない理由
まずは、素直に typeof を見てみます。
const d = new Date();
console.log(typeof d); // "object"
JavaScriptDate もオブジェクトの一種なので、typeof ではただの "object" にしか見えません。
つまり、typeof value === "object" では「プレーンなオブジェクト」「配列」「Date」「正規表現」などが全部混ざってしまいます。
console.log(typeof {}); // "object"
console.log(typeof []); // "object"
console.log(typeof new Date()); // "object"
JavaScript「Date だけを判定したい」ときに typeof は使えない、というのが最初の重要ポイントです。
Date 判定の基本:instanceof Date
一番分かりやすい Date 判定は instanceof を使う方法です。
function isDate(value) {
return value instanceof Date;
}
console.log(isDate(new Date())); // true
console.log(isDate({})); // false
console.log(isDate("2025-02-05"));// false
console.log(isDate(null)); // false
JavaScriptvalue instanceof Date は、「その値が Date コンストラクタから作られたインスタンスかどうか」を判定します。
業務コードで「普通に new Date() で作ったものだけを扱う」なら、これでほぼ足ります。
ただし、iframe や別コンテキストをまたぐような特殊なケースでは instanceof がうまく働かないこともありますが、
一般的な Web アプリや業務システムでは、まず気にしなくて大丈夫です。
「Date っぽいけど本当に有効な日付か?」という問題
もう一つ大事なポイントがあります。new Date(...) は「失敗してもエラーを投げず、“Invalid Date” という壊れた Date オブジェクトを返す」という性質を持っています。
const d1 = new Date("2025-02-05");
const d2 = new Date("not-a-date");
console.log(d1 instanceof Date); // true
console.log(d2 instanceof Date); // true(ここがややこしい)
console.log(d1.toString()); // "Wed Feb 05 2025 ..."
console.log(d2.toString()); // "Invalid Date"
JavaScriptd2 は「Date ではあるけれど、中身が壊れている」状態です。instanceof Date だけでは、「有効な日付かどうか」までは分かりません。
そこで、「Date かどうか」と「有効な日付かどうか」を分けて考える必要があります。
「Date かつ有効な日付か」を判定するユーティリティ
業務で本当に欲しいのは、たいてい「Date であり、かつ有効な日付であるかどうか」です。
それを判定する関数を作ってみます。
function isValidDate(value) {
if (!(value instanceof Date)) return false;
return !Number.isNaN(value.getTime());
}
const d1 = new Date("2025-02-05");
const d2 = new Date("not-a-date");
console.log(isValidDate(d1)); // true
console.log(isValidDate(d2)); // false
console.log(isValidDate({})); // false
console.log(isValidDate("2025-02-05")); // false
JavaScriptここでのポイントは二つです。
一つ目は、「まず instanceof Date で Date かどうかを確認している」こと。
これで、文字列やオブジェクトが紛れ込むのを防ぎます。
二つ目は、「getTime() の結果が NaN かどうかを見ている」こと。Invalid Date の getTime() は NaN になるので、Number.isNaN で弾けます。
この isValidDate を持っておくと、「Date かつ有効な日付か?」を一発で判定できるようになります。
文字列や数値から Date を作るときの流れ
実務では、「最初から Date オブジェクトが来る」ことの方が少なくて、
多くの場合は「文字列や数値から Date を作る」ところから始まります。
例えば、API から "2025-02-05T12:34:56Z" のような文字列が返ってくるケースです。
function parseDate(value) {
if (value === null || value === undefined) return null;
const d = new Date(value);
return isValidDate(d) ? d : null;
}
console.log(parseDate("2025-02-05")); // 有効な Date
console.log(parseDate("not-a-date")); // null
console.log(parseDate(null)); // null
console.log(parseDate(1738742400000)); // タイムスタンプも OK
JavaScriptここでは、「変換」と「判定」をセットで行っています。
変換部分:new Date(value)
判定部分:isValidDate(d)
このように、「Date に変換したあと、必ず isValidDate でチェックする」というパターンを徹底すると、
「Invalid Date が紛れ込んでバグる」事故をかなり防げます。
Date 判定ユーティリティをどう分けるか
業務ユーティリティとしては、次のように役割を分けておくと使いやすくなります。
// 単に「Date インスタンスかどうか」だけを見たいとき
function isDate(value) {
return value instanceof Date;
}
// 「Date かつ有効な日付か」を知りたいとき
function isValidDate(value) {
return value instanceof Date && !Number.isNaN(value.getTime());
}
JavaScriptisDate は「型チェック」、isValidDate は「型チェック+中身の妥当性チェック」というイメージです。
どちらを使うかは、「その場で何を保証したいか」で選びます。
例えば、
- 「この関数は Date しか受け付けません」なら
isDate - 「この時点で“壊れた日付”は絶対に通したくない」なら
isValidDate
という感じです。
実務での具体的な利用イメージ
フォーム入力の日付を扱う
ユーザーがフォームで日付を入力し、それが文字列として送られてくるケースを考えます。
const raw = {
startDate: "2025-02-05",
};
const start = parseDate(raw.startDate);
if (!isValidDate(start)) {
console.log("開始日が不正です");
} else {
console.log("開始日:", start.toISOString());
}
JavaScriptここでは、「文字列 → Date に変換」「Date かつ有効かを判定」という流れを明示しています。new Date(raw.startDate) をそのまま使ってしまうと、「Invalid Date でも気づかずに先に進む」危険があります。
期間チェック(開始日と終了日の関係)
開始日と終了日の関係をチェックするような業務ロジックでも、Date 判定は必須です。
function validatePeriod(startValue, endValue) {
const start = parseDate(startValue);
const end = parseDate(endValue);
if (!isValidDate(start) || !isValidDate(end)) {
return { ok: false, reason: "日付が不正です" };
}
if (end.getTime() < start.getTime()) {
return { ok: false, reason: "終了日は開始日以降である必要があります" };
}
return { ok: true };
}
console.log(validatePeriod("2025-02-05", "2025-02-10")); // ok: true
console.log(validatePeriod("2025-02-10", "2025-02-05")); // ok: false
console.log(validatePeriod("not-a-date", "2025-02-05")); // ok: false
JavaScriptここでは、「Date かどうか」と「有効な日付かどうか」をクリアしたうえで、
「開始日と終了日の大小関係」という業務ルールをチェックしています。
小さな練習で感覚をつかむ
最後に、手を動かして慣れるためのミニ課題を提案します。
自分で isDate, isValidDate, parseDate を実装して、次の値を片っ端から試してみてください。
new Date(), new Date("2025-02-05"), new Date("not-a-date"), "2025-02-05", "not-a-date", 1738742400000, {}, null, undefined
それぞれに対して、「isDate はどう返すか」「isValidDate はどう返すか」「parseDate は何を返すか」をコンソールに出してみると、
「型としての Date」と「有効な日付としての Date」を頭の中でちゃんと分けて考えられるようになります。
