🍭

JavaScript で Invalid Date を判定する

2020/11/29に公開
2

はじめに

この記事は #EveOneZenn (Everyday One Zenn) vol.07 です。

JavaScript の Date クラスが返す Invalid Date を判定する方法についてまとめます。

(過去に別所で公開していた記事の加筆版です)

前回:
https://zenn.dev/lollipop_onl/articles/eoz-ts-ncoc-transpile

Invalid Date とはなにか

Invalid Date とは、 JavaScript の Date クラスが返す、不正な日付を生成しようとしたときの値です。

const d = new Date('aaa');

d;
// js: Invalid Date

このときの変数 d は Date クラスのインスタンスであるのは変わらないので、次のコードはすべてt true となります。

const d = new Date('aaa');

typeof d === 'object';
// js: true
d instanceof Date;
// js: true

Invalid Date を判定する

JavaScript には Invalid Date に相当する値がないため、比較による判定ができません。

また、 Invalid Date を変数に入れて比較しても常に false となり判定できません。

const INVALID_DATE = new Date('invalid date');

INVALID_DATE;
// js: Invalid Date

new Date('aaa') === INVALID_DATE;
// js: false

Number.isNaN を使用する

Date クラスのインスタンスで valueOf を実行すると、 getTime() メソッドと同様 Unix 時刻からの経過ミリ秒が返されます。

new Date('2020-11-29').valueOf();
// js: 1606608000000

+new Date('2020-11-29');
// js: 1606608000000

new Date('2020-11-29').getTime();
// js: 1606608000000

getTime() メソッドは Invalid Date なインスタンスで実行すると NaN を返します。

new Date('aaa').getTime();
// js: NaN

これらを利用して、date.getTime() の結果を Number.isNaN メソッドに渡し true が返されれば、その値は Invalid Date であったということが判定できます。

const isInvalidDate = (date: Date) => Number.isNaN(date.getTime());

isInvalidDate(new Date('2020-11-29'));
// js: false

isInvalidDate(new Date('aaa'));
// js: true

参考

GitHubで編集を提案

Discussion

laticalatica

こちらの判定方法、使わせていただきました!ありがとうございました。

ちなみに、isInvalidDate(new Date('aaa')); は、提案されているコードだと false になるようです。下記を意図されていましたでしょうか?

const isInvalidDate = (date: Date) => Number.isNaN(date.getTime());
𝕤𝕚𝕞𝕠𝕔𝕙𝕖𝕖𝕤𝕚𝕞𝕠𝕔𝕙𝕖𝕖

コメントありがとうございます!
ご指摘とおり、 date.getTime() としないとコードが動作しませんでした。

こちら、isNaN(new Date('aaa'))true となりますが、Number.isNaN(new Date('aaa'))false になる差が理解できていませんでした。
Number.isNaN メソッドは引数が数値でなければ false となる)

ここでは厳密なチェックとなる Number.isNaN を使用したいため、ご提案いただきました date.getTime() を使用するよう記事を修正します!