オブジェクトが日付かどうかを確認する方法は?


601

Webページに迷惑なバグがあります。

date.GetMonth()は関数ではありません

だから、私は何か間違ったことをしていると思います。変数dateはタイプのオブジェクトではありませんDateJavascriptでデータ型を確認するにはどうすればよいですか?を追加しようとしましたif (date)が、機能しません。

function getFormatedDate(date) {
    if (date) {
       var month = date.GetMonth();
    }
}

したがって、防御的なコードを記述し、日付(1ではない)がフォーマットされないようにするには、どうすればよいですか?

ありがとう!

更新:日付の形式を確認したくありませんが、メソッドに渡されるパラメーターがgetFormatedDate()型であることを確認したいと思いますDate


日付が次の日付でないかどうかも検証する必要がある場合Invalid Datestackoverflow.com/a/44198641/5846045
Boghyon Hoffmann

回答:


1110

ダックタイピングの代替として

typeof date.getMonth === 'function'

instanceof演算子を使用できます。つまり、無効な日付に対してもtrueを返しnew Date('random_string')ます。たとえば、Dateのインスタンスでもあります。

date instanceof Date

オブジェクトがフレームの境界を越えて渡されると、これは失敗します。

これの回避策は、オブジェクトのクラスをチェックすることです

Object.prototype.toString.call(date) === '[object Date]'

29
興味がないので、フレームの境界を通過するときにこの失敗の理由を知っていますか?
Simon Lieschke、2010

85
@Simon:JSグローバルは、現在のグローバルオブジェクト(別名windowまたはself)に対してローカルです。異なるフレームには独自のグローバルオブジェクトがあり、それらのプロパティ(つまりグローバル)は個別のオブジェクトを参照します。frame1ではframe2 Dateとは異なる関数オブジェクトDateです。同じことがにも当てはまりますDate.prototype。これがinstanceof失敗の理由です。fromframe1はframe2 Date.prototypeDateインスタンスのプロトタイプチェーンの一部ではありません
Christoph

9
クリストフ、「フレーム」とは何ですか?IFRAME、FRAMESETの各フレーム、または何か(つまり、HTMLのものではなく、JS固有のもの)?
ポール

12
new Date('something') instanceof DatetrueChromeに戻ります。その場合、それは機能しません。
オキアミ

12
(プレーンオブジェクトまたは文字列ではなく)日付型オブジェクトを検出し、日付であると予想されるオブジェクトを検証することは、2つの異なるタスクです。関数への入力がさまざまなデータ型の1つになる可能性がある状況は多数あります。私の場合、取得したすべてのDateオブジェクトが有効であると信頼できます(クライアントから直接取得されたものではありません)。stackoverflow.com/questions/1353684/…–
マイケルブラックバーン

125

次のコードを使用できます。

(myvar instanceof Date) // returns true or false

6
なぜこれは受け入れられないか、より賛成された答えではないのですか?日付に.getMonthプロパティがあるかどうかを確認するだけで、誤検知がトリガーされる可能性があります。
ドレミ

24
instanceofは偽陰性を引き起こす可能性があります。彼自身の回答に対するChristophのコメントを参照してください。
Marco Mariani

2
@doremi instanceof偽陰性のトリガーのデモは次のとおり
vufufoq

68

値が標準のJS-dateオブジェクトの有効なタイプであるかどうかを確認するには、次の述語を使用できます。

function isValidDate(date) {
  return date && Object.prototype.toString.call(date) === "[object Date]" && !isNaN(date);
}
  1. dateパラメータがなかったか否かをチェックfalsy値undefinednull0""、など。)
  2. Object.prototype.toString.call(date)指定されたオブジェクトタイプのネイティブ文字列表現を返します-私たちの場合"[object Date]"date.toString()親メソッドをオーバーライドするので、必要に応じて、.callまたは直接.applyからメソッドObject.prototypeを..
    • 同じコンストラクタ名を持つユーザー定義のオブジェクトタイプをバイパスします(例: "Date")
    • またはとは対照的にinstanceof、さまざまなJSコンテキスト(iframeなど)で機能Date.prototype.isPrototypeOfます。
  3. !isNaN(date)最後に、値がでないかどうかを確認しますInvalid Date

1
うわーisNaN、チェックに使用できますDate。これは、PHPレベルの即興性です。
ニック

@Nick日付は数値ですが。
ジョサイア

@ジョサイアまあ、確かに、すべてのコンテキストを削除すると、そこにタイムスタンプがありtypeof Date.now() === "number"ますtypeof new Date() === "object"。しかし、より現実的には、日付は時間と空間内の場所です。
ニック

39

関数はgetMonth()ではなくGetMonth()です。

とにかく、これを行うと、オブジェクトにgetMonthプロパティがあるかどうかを確認できます。これは、必ずしもオブジェクトが日付であることを意味するのではなく、getMonthプロパティを持つすべてのオブジェクトです。

if (date.getMonth) {
    var month = date.getMonth();
}

3
呼び出し可能かどうかを確認しますif (date.getMonth && typeof date.getMonth === "function") {...}
。–アロソ

20

上記のように、使用する前に関数が存在するかどうかを確認するのがおそらく最も簡単です。これがDateであり、getMonth()関数を含むオブジェクトだけではないことに本当に気になる場合は、次のことを試してください。

function isValidDate(value) {
    var dateWrapper = new Date(value);
    return !isNaN(dateWrapper.getDate());
}

これは、値の場合は値のクローンを作成するかDate、無効な日付を作成します。次に、新しい日付の値が無効かどうかを確認できます。


1
これでうまくいきました。ただし、0や1などの1桁を渡すと、それは有効な日付として扱われます。
Ricardo Sanchez

そうです、@ RicardoSanchez。Object.prototype.toString.call(value) === '[object Date]'可能であれば、受け入れられた回答()を使用することをお勧めします。この回答のメソッドは、valueがに変換可能かどうかを実際に示していますDate
bdukes 2015年

18

すべてのタイプで、Objectプロトタイプ関数を作成しました。あなたに役立つかもしれません

Object.prototype.typof = function(chkType){
      var inp        = String(this.constructor),
          customObj  = (inp.split(/\({1}/))[0].replace(/^\n/,'').substr(9),
          regularObj = Object.prototype.toString.apply(this),
          thisType   = regularObj.toLowerCase()
                        .match(new RegExp(customObj.toLowerCase()))
                       ? regularObj : '[object '+customObj+']';
     return chkType
            ? thisType.toLowerCase().match(chkType.toLowerCase()) 
               ? true : false
            : thisType;
}

これで、次のようなタイプを確認できます。

var myDate     = new Date().toString(),
    myRealDate = new Date();
if (myRealDate.typof('Date')) { /* do things */ }
alert( myDate.typof() ); //=> String

[ 2013年3月の編集 ]進行中の洞察に基づいて、これはより良い方法です。

Object.prototype.is = function() {
        var test = arguments.length ? [].slice.call(arguments) : null
           ,self = this.constructor;
        return test ? !!(test.filter(function(a){return a === self}).length)
               : (this.constructor.name ||
                  (String(self).match ( /^function\s*([^\s(]+)/im)
                    || [0,'ANONYMOUS_CONSTRUCTOR']) [1] );
}
// usage
var Some = function(){ /* ... */}
   ,Other = function(){ /* ... */}
   ,some = new Some;
2..is(String,Function,RegExp);        //=> false
2..is(String,Function,Number,RegExp); //=> true
'hello'.is(String);                   //=> true
'hello'.is();                         //-> String
/[a-z]/i.is();                        //-> RegExp
some.is();                            //=> 'ANONYMOUS_CONSTRUCTOR'
some.is(Other);                       //=> false
some.is(Some);                        //=> true
// note: you can't use this for NaN (NaN === Number)
(+'ab2').is(Number);                 //=> true


8

私が見つけた最良の方法は:

!isNaN(Date.parse("some date test"))
//
!isNaN(Date.parse("22/05/2001"))  // true
!isNaN(Date.parse("blabla"))  // false

これは機能しません。あなたの本当の行は実際には偽であり、問​​題はオブジェクトが日付オブジェクトであるかどうかを確認することです...
Clint

1
@jspassovの回答は、文字列が日付であるかどうかでより正確になります。探していたもの。ありがとう!!
Anant、2016年

これは、文字列が日付であるかどうかを単にチェックするための最良の答えです
James Gentes

3

Dateオブジェクトに固有の関数が存在するかどうかを確認できます。

function getFormatedDate(date) {
    if (date.getMonth) {
        var month = date.getMonth();
    }
}

3

すべての回避策の代わりに、以下を使用できます。

dateVariable = new Date(date);
if (dateVariable == 'Invalid Date') console.log('Invalid Date!');

私はこのハックをもっとよく見つけました!


2

また、短い形式を使用できます

function getClass(obj) {
  return {}.toString.call(obj).slice(8, -1);
}
alert( getClass(new Date) ); //Date

またはこのようなもの:

(toString.call(date)) == 'Date'

2

私はずっと簡単な方法を使用してきましたが、これがES6でのみ利用できるかどうかはわかりません。

let a = {name: "a", age: 1, date: new Date("1/2/2017"), arr: [], obj: {} };
console.log(a.name.constructor.name); // "String"
console.log(a.age.constructor.name);  // "Number"
console.log(a.date.constructor.name); // "Date"
console.log(a.arr.constructor.name);  // "Array"
console.log(a.obj.constructor.name);  // "Object"

ただし、コンストラクタがないため、これはnullまたはundefinedでは機能しません。


コンストラクター名が "Date"のカスタムメイドオブジェクト"Date"も返されます。これは、パラメーターにgetMonthプロパティがあるかどうかを確認するのと同じくらい危険です。
Boghyon Hoffmann 2017

2
@boghyonは、すでに定義済みのJavascript標準ライブラリのコンストラクター名でオブジェクトを作成した人が、そもそもベストプラクティスに従っていないように聞こえます。これは、lodashをダウンロードしてから独自のlodashモジュールを作成し、機能することを期待するようなものです。
mjwrazor 2017年

1

この関数は、true日付またはfalseそれ以外の場合に戻ります。

function isDate(myDate) {
    return myDate.constructor.toString().indexOf("Date") > -1;
} 

1
isDate(new (function AnythingButNotDate(){ })())リターンtrue
Boghyon Hoffmann


1

try / catchを使用するアプローチ

function getFormatedDate(date = new Date()) {
  try {
    date.toISOString();
  } catch (e) {
    date = new Date();
  }
  return date;
}

console.log(getFormatedDate());
console.log(getFormatedDate('AAAA'));
console.log(getFormatedDate(new Date('AAAA')));
console.log(getFormatedDate(new Date(2018, 2, 10)));


0

実際には、日付のタイプになりObjectます。ただし、オブジェクトにgetMonthメソッドがあるかどうか、および呼び出し可能かどうかを確認できます。

function getFormatedDate(date) {
    if (date && date.getMonth && date.getMonth.call) {
       var month = date.getMonth();
    }
}

2
クリストフの答えはより正確です。「呼び出し」プロパティがあることは、それが関数であることを必ずしも意味しません!
Chetan Sastry

-1

以下のコードで検証することもできます

var a = new Date();
a.constructor === Date
/*
true
*/

ここに画像の説明を入力してください


のコンストラクタfunction Date() {/*...*/}Dateです。つまり、コンストラクタ関数を単純に比較するとエラーが発生しやすくなり、多くの場合、誤検知が発生します。stackoverflow.com/a/44198641/5846045で
Boghyon Hoffmann

-1

この回答に触発され、このソリューションは私の場合に機能します(APIから受け取った値が日付かどうかを確認する必要がありました):

!isNaN(Date.parse(new Date(YourVariable)))

このようにして、クライアントからのランダムな文字列やその他のオブジェクトである場合、それが日付のようなオブジェクトであるかどうかを確認できます。


-2

使っていただけませんか

function getFormatedDate(date) {
    if (date.isValid()) {
       var month = date.GetMonth();
    }
}

1
いいえ、日付オブジェクトだけがisValidメソッドを持っています
nikk wong

2
@grumpy @nikkwongいいえ、いいえ。標準の日付オブジェクトにははありませんisValid。そのようなAPIを持つのは、moment.jsだけです
Boghyon Hoffmann
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.