Bir nesnenin tarih olup olmadığını nasıl kontrol edebilirim?


601

Bir web sayfasında can sıkıcı bir hata var:

date.GetMonth () bir işlev değildir

Sanırım yanlış bir şey yaptığımı. Değişken datetüründe bir nesne değildir Date. Javascript'te bir veri tipini nasıl kontrol edebilirim? Bir eklemeye çalıştım if (date), ama işe yaramıyor.

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

Peki, savunma kodu yazmak ve tarihin (hangisi değil) biçimlendirilmesini önlemek istersem, bunu nasıl yaparım?

Teşekkürler!

GÜNCELLEME: Ben tarih biçimini kontrol etmek istemem, ama emin yönteme geçirilen parametre olduğunu olmasını istediğiniz getFormatedDate()tiptedir Date.


Durumda da ister doğrulanması gereken tarih bir değildir Invalid Date: stackoverflow.com/a/44198641/5846045
Boghyon Hoffmann

Yanıtlar:


1109

Üzerinden yazarak ördek alternatif olarak

typeof date.getMonth === 'function'

instanceofişleci kullanabilirsiniz , yani geçersiz tarihler için de true değerini döndürür, örneğin new Date('random_string')Date örneğidir

date instanceof Date

Nesneler çerçeve sınırları dışına aktarılırsa bu başarısız olur.

Bunun için bir çözüm, nesnenin sınıfını

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

28
Çerçeve sınırlarını geçerken bu başarısızlığın nedenini biliyor musunuz?
Simon Lieschke

85
@Simon: JS globalleri geçerli global nesnede (aka windowveya self) yereldir ; farklı çerçevelerin kendi global nesneleri vardır ve özellikleri (yani globaller) farklı nesnelere karşılık gelir: Dateframe1 öğesinde Dateframe2 öğesinden farklı bir işlev nesnesidir ; Aynı durum Date.prototype, instanceofbaşarısızlığın nedeni de budur : Date.prototypeframe1'den frame2'den Dateörneklerin prototip zincirinin bir parçası değildir
Christoph

9
Christoph, ne "çerçeve" diyorsun? IFRAME, FRAMESET'teki her kare veya başka bir şey (HTML-değil JS'ye özgüdür)?
Paul

12
new Date('something') instanceof DatetrueChrome'da döner . O zaman işe yaramaz.
krillgar

12
Bir Tarih türü nesnesini algılama (düz bir Nesne veya dize yerine) ve Tarih olmasını beklediğiniz bir nesneyi doğrulamak iki farklı görevdir. İşlevinize yapılan girdinin bir dizi farklı veri türünden biri olabileceği birkaç durum vardır. Benim durumumda, aldığım herhangi bir Date nesnesinin geçerli olduğuna güvenebilirim (doğrudan bir istemciden gelmiyor) Doğrulama endişe ediyorsa, burada birkaç seçenek içeren bir gönderi var. stackoverflow.com/questions/1353684/…
Michael Blackburn

125

Aşağıdaki kodu kullanabilirsiniz:

(myvar instanceof Date) // returns true or false

6
Bu neden kabul edilen veya daha fazla onaylanmamış cevap değil? Tarihin bir .getMonth özelliğine sahip olup olmadığını kontrol etmek, yanlış bir pozitif tetikleyebilir.
doremi

24
instanceof yanlış negatifleri tetikleyebilir, bkz. Christoph'un kendi cevabı hakkındaki yorumu.
Marco Mariani

2
@doremi İşte instanceofyanlış negatif tetikleme demosu : jsbin.com/vufufoq/edit?html,js,console
Boghyon Hoffmann

68

Değerin standart JS-date nesnesinin geçerli bir türü olup olmadığını kontrol etmek için bu yüklemden yararlanabilirsiniz:

function isValidDate(date) {
  return date && Object.prototype.toString.call(date) === "[object Date]" && !isNaN(date);
}
  1. dateparametresi olup olmadığı kontrol falsy değeri ( undefined, null, 0, "", vs ..)
  2. Object.prototype.toString.call(date)verilen nesne türünün yerel dize temsilini döndürür - Bizim durumumuzda "[object Date]". Çünkü date.toString()geçersiz kılma üst yöntemi , biz gereken .callveya .applygelen yöntemiyle Object.prototypedoğrudan hangi ..
  3. !isNaN(date)son olarak değerin bir olup olmadığını kontrol eder Invalid Date.

1
Wow isNaNkontrol etmek için kullanılabilir Date. Bu PHP'nin bazı inanç düzeyi.
Nick

@Hiçbir tarih bir sayı olsa.
Josiah

@Josiah Tabi, tüm içeriği kaldırılıyor orada bir zaman damgası var: typeof Date.now() === "number"ama: typeof new Date() === "object". Daha gerçekçi olarak, bir tarih bir zaman ve uzayda bir konumdur.
Nick

39

Fonksiyon getMonth()değil GetMonth().

Her neyse, bunu yaparak nesnenin getMonth özelliğine sahip olup olmadığını kontrol edebilirsiniz. Nesnenin bir Tarih olduğu anlamına gelmez, sadece getMonth özelliğine sahip herhangi bir nesne anlamına gelir.

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

3
if (date.getMonth && typeof date.getMonth === "function") {...}
Çağrılabilir

20

Yukarıda belirtildiği gibi, muhtemelen işlevin kullanmadan önce var olup olmadığını kontrol etmek en kolay yoldur. DateSadece bir getMonth()işleve sahip bir nesne değil, bir a olmasını gerçekten önemsiyorsanız , şunu deneyin:

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

Bu, a değerinin bir klonunu Dateoluşturur veya geçersiz bir tarih oluşturur. Ardından yeni tarih değerinin geçersiz olup olmadığını kontrol edebilirsiniz.


1
Bu benim için çalıştı, teşekkürler. Ancak, 0 veya 1 gibi tek bir rakam iletirseniz, bunu geçerli bir Tarih olarak kabul eder ... herhangi bir düşünce?
Ricardo Sanchez

Bu doğru, @RicardoSanchez. Muhtemelen kabul edilen cevabı ( Object.prototype.toString.call(value) === '[object Date]') kullanmak istiyorsunuz, eğer mümkünse rakamlar alacaksınız. Bu yanıttaki yöntem gerçekten size valuea dönüştürülebilir olup olmadığını söyler Date.
bdukes

18

Tüm tipler için bir Nesne prototip işlevi hazırladım. Bu sizin için yararlı olabilir

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;
}

Şimdi böyle bir türü kontrol edebilirsiniz :

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

İlerleyen kavrayışa dayanarak [ Mart 2013'ü düzenle ] bu daha iyi bir yöntemdir:

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

Bulduğum en iyi yol:

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

Bu işe yaramıyor. Gerçek çizginiz aslında yanlış ve soru, bir nesnenin bir tarih nesnesi olup olmadığını kontrol etmektir ...
Clint

1
@jspassov yanıtı, bir dizenin tarih olup olmadığı konusunda daha doğrudur. Aradığım şey. Teşekkürler!!
Anant

Bu, bir dizenin tarih olup olmadığını kontrol etmek için en iyi cevaptır
James Gentes

3

Date nesnesine özgü bir işlevin var olup olmadığını kontrol edebilirsiniz:

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

3

Tüm geçici çözümler yerine aşağıdakileri kullanabilirsiniz:

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

Bu hack'i daha iyi buldum!


2

Ayrıca kısa form kullanabilirsiniz

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

ya da bunun gibi bir şey:

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

2

Çok daha basit bir yol kullanıyorum ama bunun sadece ES6'da mevcut olup olmadığından emin değilim.

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"

Ancak, yapıcıları olmadığı için bu null veya undefined üzerinde çalışmaz.


"Date" yapıcı adına sahip özel yapılmış herhangi bir nesne "Date"de, parametrenin getMonthözelliğine sahip olup olmadığını kontrol etmek kadar riskli bir şekilde geri döner .
Boghyon Hoffmann

2
@boghyon, önceden tanımlanmış bir Javascript standart kütüphanesinin yapıcı adına sahip bir nesneyi oluşturan kişi en iyi uygulamaları takip etmiyor gibi görünüyor. Bu, lodash'ı indirip kendi lodash modülünüzü oluşturmak ve işlerin çalışmasını beklemek gibi bir şey olacaktır.
mjwrazor

1

Bu işlev trueTarih veya falsebaşka bir durumda döndürür:

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

1
isDate(new (function AnythingButNotDate(){ })())dönertrue
Boghyon Hoffmann


1

Bir dene / yakala kullanan bir yaklaşım

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

Aslında tarih türü olacaktır Object. Ancak nesnenin getMonthyöntemi olup olmadığını ve çağrılabilir olup olmadığını kontrol edebilirsiniz .

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

2
Christoph'un cevabı daha doğru. 'Call' özelliğine sahip olmak, mutlaka bir işlev olduğu anlamına gelmez!
Chetan Sastry

-1

Aşağıdaki kodla da doğrulayabiliriz

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

resim açıklamasını buraya girin


Kurucusu function Date() {/*...*/}da Date. Yani sadece yapıcı işlevini karşılaştırmak hataya yatkındır ve bu da genellikle yanlış pozitif sonuç verir. İle kullanıcı tanımlı bir nesne türü Baypas stackoverflow.com/a/44198641/5846045
Boghyon Hoffmann

-1

Bu cevaptan esinlenerek , bu çözüm benim durumumda çalışır (API'dan alınan değerin bir tarih olup olmadığını kontrol etmem gerekiyordu):

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

Bu şekilde, bir istemciden veya başka bir nesneden gelen rastgele bir dize ise, bunun Tarih benzeri bir nesne olup olmadığını öğrenebilirsiniz.


-2

Sadece kullanamaz mısın

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

1
Hayır, yalnızca tarih nesnesinin isValidyöntemi vardır
nikk wong

2
@grumpy @nikkwong Hayır ve hayır. Standart tarih nesnesi içermiyor isValid. Sadece moment.js'de böyle bir API vardır.
Boghyon Hoffmann
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.