Edited at

JavaScript (node.js/chrome/firefox) で Invalid Date を判定する

More than 3 years have passed since last update.

2016/09/16 取り直しました


  • node v6.6.0

  • chrome 53.0.2785.116

  • firefox 48.0.2

無効な時間文字列をnew Dateに渡すとInvalid DateというDateオブジェクトが返されます。

var str = "2014-09-A";

var d = new Date(str); // Invalid Date
d.constructor; // [Function: Date]
if(d){
console.log("d is truthy"); // d is truthy
}else{
console.log("d is falsy");
}

おまけにこいつ自体は真値となります。

判別方法として


  1. d.toString() === "Invalid Date"

  2. ""+d === "Invalid Date"

  3. isNaN(d)

  4. isNaN(+d)

  5. isNaN(d.getTime())

などがあります(3と4はほぼ同じ)。

modelで日付が含まれており、そのvalidationを行うようなときには結構な回数が呼ばれるのでなんとかしたいところなのでそれぞれパフォーマンスを調べました

結論から言うと1が最も速く、次が5になります。

n=1000000

項番

node msec
chrome msec
firefox msec

1
d.toString() === "Invalid Date"
166
171
951

2
""+d === "Invalid Date"
424
378
1173

3
isNaN(d)
258
210
1380

4
isNaN(+d)
287
230
1406

5
isNaN(d.getTime())
15
11
1208


  • 検証コード

const d = new Date("2014-09-A");

n=1000000; console.time(1); while(n--){ d.toString() === "Invalid Date"} console.timeEnd(1);
n=1000000; console.time(2); while(n--){ ""+d === "Invalid Date"} console.timeEnd(2);
n=1000000; console.time(3); while(n--){ isNaN(d) } console.timeEnd(3);
n=1000000; console.time(4); while(n--){ isNaN(+d)} console.timeEnd(4);
n=1000000; console.time(5); while(n--){ isNaN(d.getTime())} console.timeEnd(5);


追記(2014/10/09 22:27:15)

ちなみにmoment.js#isValidは最遅でおおよそ4000msかかります。