JavaScript'te "geçersiz tarih" Tarih örneğini algılama


1493

JS'de geçerli ve geçersiz tarih nesneleri arasındaki farkı söylemek istiyorum, ancak nasıl olduğunu anlayamadım:

var d = new Date("foo");
console.log(d.toString()); // shows 'Invalid Date'
console.log(typeof d); // shows 'object'
console.log(d instanceof Date); // shows 'true'

Bir isValidDateişlev yazmak için herhangi bir fikrin var mı?

  • Date.parseTarih dizelerinin ayrıştırılması için önerilen kül , tarih dizesinin geçerli olup olmadığını kontrol etmek için yetkili bir yol sunar.
  • Mümkünse tercih edeceğim şey, API'mın bir Date örneğini kabul etmesi ve geçerli olup olmadığını kontrol edebilmesidir. Borgar'ın çözümü bunu yapıyor, ancak tarayıcılarda test etmem gerekiyor. Ayrıca daha zarif bir yol olup olmadığını merak ediyorum.
  • Ash, API'mın Dateörnekleri kabul etmediğini düşünmemi sağladı , bunu doğrulamak en kolayı olurdu.
  • Borgar bir Dateörnek için test yapılmasını ve ardından Date's zaman değerini test etmeyi önerdi . Tarih geçersizse, zaman değeri olur NaN. ECMA-262 ile kontrol ettim ve bu davranış standart, tam olarak aradığım şey.

18
return ( Object.prototype.toString.call(d) === "[object Date]" && !isNaN(d.getTime()) );
İf ifadesini

3
@styfle - sanırım bir stil tercihi: Tür denetimini eşitlik mantığından ayırmayı daha net buluyorum.
orip

26
@orip söylem, sorularda kesinlikle cesaret kırıcı olan şeydir. Bunun arkasındaki mantığı öğrenmek için lütfen ilgili meta konulara bakın. Sorunun kendisine kendi sorusuna bir cevap vermek site politikasına aykırıdır. OTOH, cevaplar için teşekkür ve cevabınızda "EDIT" olması tipik tüylerdir. Sizi SO'nun ne olduğunu ve nasıl kullanılacağını bilmeyen ve bunu öğrenmek istemeyen bir kişi olarak tanımlamak için en yüksek soruyu sormak istiyorsanız - misafirim olun.

14
@orip: "Kayıp" değildi; tekrar görmek isterseniz, sorunun düzeltme geçmişini karıştırmaya devam ediyor. Ama bir soruya ait değil. 37k temsilcisi bunu bilmelisiniz.
Orbit'te Hafiflik Yarışları

6
Lütfen düzenleme savaşını durdurun. Bu sorudaki düzenlemeler meta üzerinde tartışılmaktadır . Lütfen bu yayını daha fazla düzenlemeyin / geri almayın. Önceki düzenlemelere / geri almalara katılmıyorsanız veya bunlarla ilgili herhangi bir yorumunuz varsa, lütfen burada değil, bu meta dizide yayınlayın.
Lundin

Yanıtlar:


1301

İşte nasıl yaparım:

if (Object.prototype.toString.call(d) === "[object Date]") {
  // it is a date
  if (isNaN(d.getTime())) {  // d.valueOf() could also work
    // date is not valid
  } else {
    // date is valid
  }
} else {
  // not a date
}

Güncelleme [2018-05-31] : Diğer JS bağlamlarındaki Date nesneleriyle (harici pencereler, çerçeveler veya iframe'ler) ilgilenmiyorsanız, bu daha basit form tercih edilebilir:

function isValidDate(d) {
  return d instanceof Date && !isNaN(d);
}

21
instanceof kareler arasında kırılıyor. Ördek yazma da gayet iyi çalışabilir: validDate == d && d.getTime &&! İsNaN (d.getTime ()); - Soru genel bir fayda işlevi için olduğundan daha katı olmayı tercih ederim.
09:14

11
@Borgar, cevabımı buldum: "Çok çerçeveli DOM ortamlarında komut dosyası oluşturma söz konusu olduğunda sorunlar ortaya çıkıyor. Özetle, bir iframe içinde oluşturulan Array nesneleri [[Prototype]] 'i başka bir iframe içinde oluşturulan dizilerle paylaşmıyor "Yapıcıları farklı nesneler ve bu nedenle hem instanceof hem de yapıcı denetimleri başarısız oluyor."
Ash

64
Hatta gerek yok d.getTimesadeceisNan(d)
TecHunter

8
Bu şekilde basitleştirilebilir:d instanceof Date && !isNaN(d.getTime())
Zorgatone

5
Cevabınız için teşekkürler, ancak @Borgar ve @blueprintChris'i vurgulamak istiyorum: 1örneğin rakamı ayrıştırırsam, yine de Mon Jan 01 2001 00:00:00gerçekten bir tarih olan geçerli bir tarihim olur , ancak başvurumun amacı için tamamen işe yaramaz . Bu nedenle, en azından benim durumumda daha fazla girdi doğrulaması gerekli. Bu cevap bir dateObjectdeğil Date!
2018

264

Kullanmak yerine new Date()şunları kullanmalısınız:

var timestamp = Date.parse('foo');

if (isNaN(timestamp) == false) {
  var d = new Date(timestamp);
}

Date.parse()01 / Ocak / 1970'den bu yana milisaniye sayısını temsil eden bir tam sayı döndürür. NaNSağlanan tarih dizesini ayrıştıramıyorsa geri döner .


119
-1 Neden bu kadar çok oy aldığını Date.parsebilmiyorsanız, uygulamaya bağlıdır ve genel tarih dizelerini ayrıştırmak için kesinlikle güvenilmemelidir. Popüler tarayıcılarda doğru olarak ayrıştırılan tek bir biçim yoktur, kullanımda olanların çok daha azı (ancak sonunda ES5'te belirtilen ISO8601 biçimi iyi olmalıdır).
RobG

1
Bunu kullanırsanız, new Date('foo')bu Date.parse('foo')yöntemle eşdeğerdir . Bakınız: developer.mozilla.org/tr-TR/docs/Web/JavaScript/Reference/… @RobG'nin söylediği şey, bunun için de geçerlidir.
golddragon007

2
Bu test Chrome'da başarısız olur. Örneğin, Chrome'daki Date.parse ('AAA-0001') bana bir numara veriyor.
Nick

başarısız oldu ... tüm sayısal değerleri tespit et
Hos Mercury

109

Bir Datenesnenin geçerliliğini şu dyolla kontrol edebilirsiniz:

d instanceof Date && isFinite(d)

Çerçeveler arası sorunları önlemek için, instanceofçek ile değiştirilebilir

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

Borgar'ın cevabındakigetTime() gibi bir çağrı gereksizdir ve her ikisi de dolaylı olarak sayıya dönüşür .isNaN()isFinite()


Bunu chrome - Object.prototype.toString.call (yeni Tarih ("2013-07-09T19: 07: 9Z")) içinde deneyin. "[Object Date]" değerini döndürür. Size göre, bu nedenle, "2013-07-09T19: 07: 9Z", geçerli bir tarih olmalıdır. Ama öyle değil. Var dateStr = new Date ("2013-07-09T19: 07: 9Z") yaparak tekrar kromda doğrulayabilirsiniz. dateStr Geçersiz tarih döndürür.
Tenten

2
@Tintin: bunun için ne isFinite()var - çekin toString.call()sadece bir instanceofkısmının yerini alıyor
Christoph

'[Object Date]' ile karşılaştırmak İngilizce olmayan tarayıcılarla çalışır mı? Şüpheliyim.
kristianp

2
@kristianp aslında muhtemelen ECMAScript spesifikasyonunun bir parçası olacaktır ve hatta bir parçasıdır. Ama evet, çirkin gözüküyor.
binki

Emin kullanarak herhangi gerçek dünya avantajı varsa değilim rağmen Bana göre ilk yaklaşım burada çok iyi seçenektir isFiniteüzerinde isNaN(sadece iyi hem işi Date(Infinity)). Eğer tersi koşulunu istiyorsanız Dahası, biraz daha basit olur: if (!(date instanceof Date) || isNaN(date)).
Andrew

86

Çözümüm, geçerli bir tarih nesnesi alıp almadığınızı kontrol etmektir:

uygulama

Date.prototype.isValid = function () {
    // An invalid date object returns NaN for getTime() and NaN is the only
    // object not strictly equal to itself.
    return this.getTime() === this.getTime();
};  

kullanım

var d = new Date("lol");

console.log(d.isValid()); // false

d = new Date("2012/09/11");

console.log(d.isValid()); // true

28
isNaNNaN için test etmek için daha açık bir yoldur
orip

1
Ve yine de, her zaman kendi sürümlerini yazan insanları buluyorsun :) documentcloud.github.com/underscore/docs/…
Ash Clarke

4
underscore.js'ye saygı duyduğum için bu biraz araştırma gerektirdi. isNaN("a") === true, süre ("a" !== "a") === false. Düşünmeye değer. +1
orip

8
Burada bulduğum 3 ana çözüm için performansı test ettim. Tebrikler, kazanan sizsiniz! jsperf.com/detecting-an-invalid-date
zVictor

2
@Ali Bu geçerli bir tarih nesnesidir. new Date("02-31-2000") // Thu Mar 02 2000 00:00:00 GMT+0000 (GMT Standard Time). Tarih oluşturucuya bir dize geçiriyorsanız, güvenilir bir sonuç almak için standart bir dize iletmeniz gerekir. Özellikle, "Dize Date.parse () yöntemi tarafından tanınan bir biçimde olmalıdır". developer.mozilla.org/tr-TR/docs/Web/JavaScript/Reference/…
Ash Clarke

71

geçerli tarihi kontrol etmek için en kısa cevap

if(!isNaN(date.getTime()))

2
Tek sorun, tarih Date türünde değilse; bir JS hatası alıyorsunuz.
Andrew

@Andrew tarihi Object oluşturmanız gerekiyor ve zaten bir nesneniz varsa kullanındate && !isNaN(date.getTime())
abhirathore2006

dateDate türünde değilse , yine de bir JS hatası verir . Örneğin: var date = 4; date && !isNaN(date.getTime());.
Andrew

@Andrew use date instanceof Date && !isNaN(date.getTime())
abhirathore2006

3
Doğru, 8 yıl önceki diğer cevaplar gibi. : P stackoverflow.com/a/1353945/2321042
Andrew

45

Moment.js'yi kullanabilirsiniz .

İşte bir örnek:

var m = moment('2015-11-32', 'YYYY-MM-DD');
m.isValid(); // false

Doğrulama bölümünde belgelerinde oldukça açıktır.

Ayrıca, aşağıdaki ayrıştırma bayrakları geçersiz bir tarihle sonuçlanır:

  • overflow: 13. ay, ayın 32. günü (veya artık olmayan yıllarda 29 Şubat), yılın 367. günü vb. Gibi bir tarih alanının taşması, geçersiz birimin dizinini içeriyor #invalidAt ile eşleşmek için (aşağıya bakın); -1 taşma anlamına gelir.
  • invalidMonth: Moment ('Mart', 'MMMM') gibi geçersiz bir ay adı ;. Geçersiz ay dizesinin kendisini veya null değerini içerir.
  • empty: Moment ('bu saçmalık') gibi ayrıştırılabilir hiçbir şey içermeyen bir giriş dizesi; Boole.
  • Vb.

Kaynak: http://momentjs.com/docs/


6
Uygulanması son derece kolay olan en iyi çözüm, herhangi bir biçimlendirmeyle (benim durumum gg / AA / yyyy) çalışır, artık yılları da bilir ve geçersiz tarihleri ​​(yani 29/02/2015) tek başına geçerli olanlara dönüştürmez (yani 30/03/2015). Formad gg / aa / yyyy'de bir tarihi kontrol etmek için sadece kullanmak zorunda kaldımmoment("11/06/1986", "DD/MM/YYYY").isValid();
Rafael Merlin


2
Bu kullanım amortismana tabi tutulmadı. Biçim dizesi olmayan çağrı momenti (giriş) amortismana tabi tutulur (giriş ISO biçimlendirilmediği sürece).
Chet

2
Birçok tarih işlenirken bu yöntem son derece yavaş olabilir. Bu durumlarda normal ifade kullanmak daha iyidir.
Grid Trekkor

2
Moment.js kullanımı basit olabilir, ancak muazzam bir yüktür. Bu kütüphane BÜYÜK. Cevabını reddettim.
Mick

38

JQuery UI DatePicker widget'ının biçim ve geçerliliği kontrol eden çok iyi bir tarih doğrulama aracı yöntemine sahip olduğunu belirtmek isteriz (örneğin, 01/33/2013 tarihlerine izin verilmez).

Sayfanızdaki tarih seçici widget'ını bir kullanıcı arayüzü öğesi olarak kullanmak istemeseniz bile, her zaman .js kütüphanesini sayfanıza ekleyebilir ve ardından, doğrulamak istediğiniz değeri ona aktararak doğrulama aracı yöntemini çağırabilirsiniz. Hayatı daha da kolaylaştırmak için, bir JavaScript Tarihi nesnesi değil, girdi olarak bir dize alır.

Bkz. Http://api.jqueryui.com/datepicker/

Bir yöntem olarak listelenmez, ancak orada - bir yardımcı program işlevi olarak. Sayfayı "parsedate" için aradığınızda şunları bulabilirsiniz:

$ .datepicker.parseDate (biçim, değer, ayarlar) - Belirtilen biçime sahip bir dize değerinden bir tarih ayıklar.

Örnek kullanım:

var stringval = '01/03/2012';
var testdate;

try {
  testdate = $.datepicker.parseDate('mm/dd/yy', stringval);
             // Notice 'yy' indicates a 4-digit year value
} catch (e)
{
 alert(stringval + ' is not valid.  Format must be MM/DD/YYYY ' +
       'and the date value must be valid for the calendar.';
}

(Tarih biçimlerini belirlemeye ilişkin daha fazla bilgiyi http://api.jqueryui.com/datepicker/#utility-parseDate adresinde bulabilirsiniz )

Yukarıdaki örnekte, '01 / 03/2012 'belirtilen biçimde takvimde geçerli bir tarih olduğu için uyarı iletisini göremezsiniz. Ancak, 'stringval' değerini '13 / 04/2013 'e eşit yaparsanız, '13 / 04/2013' değeri takvimde geçerli olmadığından uyarı iletisini alırsınız.

Geçirilen bir dize değeri başarıyla ayrıştırılırsa, 'testdate' değeri, iletilen dize değerini temsil eden bir Javascript Date nesnesi olur. Değilse, tanımsız olurdu.


3
İngilizce / yerel olmayan tarih biçimleriyle çalışan ilk yanıt olduğu için oy verin.
balta.

26

Christoph'un yaklaşımını gerçekten sevdim (ancak oy kullanmak için yeterli bir üne sahip değildim). Benim kullanım için, her zaman bir Date nesnesi olacak biliyorum, bu yüzden sadece geçerli bir () yöntemi ile tarihi uzattım.

Date.prototype.valid = function() {
  return isFinite(this);
}

Şimdi bunu yazabilirim ve sadece koddaki isFinite'i kontrol etmekten çok daha açıklayıcı ...

d = new Date(userDate);
if (d.valid()) { /* do stuff */ }

10
Prototip genişletiliyor mu? Bu büyük bir JavaScript hayır hayır!
Jasdeep Khalsa

isFiniteBenim için mükemmel çalıştı çünkü upvoting . Ama evet, prototipi genişletmek anlamsız. !isFiniteBir üzerinde Dategerçeğini yakalayacak Dateolduğunu Invalid Date. Ayrıca bağlamımın Node içinde olduğunu belirtmek gerekir.
Staghouse

23
// check whether date is valid
var t = new Date('2011-07-07T11:20:00.000+00:00x');
valid = !isNaN(t.valueOf());

5
@Borgar 2 yıl önce yazdı aynı ... Yenilikler ??
mavimsi

11
Çirkin iç içe if ifadeleri yerine iki satırdır.
Cypher

17

bu cıvıltı ile geçerli txDate.value biçimini kontrol edebilirsiniz. yanlış biçimdeyse Date obejct somutlaştırılmadı ve nt değerini dt'ye döndür.

 var dt = new Date(txtDate.value)
 if (isNaN(dt))

Ve @ MiF'nin kısaca önerdiği gibi

 if(isNaN(new Date(...)))

isNaN (yeni Tarih (...)) - basit ve kısa yöntem
MiF

1
@MiF evet, cevabınızı önerinizle
güncelliyorum

16

Yıl, ay ve tarih için değerleri doğrulamak için aşağıdaki kodu kullanın.

function createDate(year, month, _date) {
  var d = new Date(year, month, _date);
  if (d.getFullYear() != year 
    || d.getMonth() != month
    || d.getDate() != _date) {
    throw "invalid date";
  }
  return d;
}

Ayrıntılar için bkz . Javascript'teki tarihi kontrol etme


strkullanılmıyor.
samis

12

Burada zaten çok fazla karmaşık cevap var, ancak basit bir satır yeterli (ES5):

Date.prototype.isValid = function (d) { return !isNaN(Date.parse(d)) } ;

hatta ES6'da:

Date.prototype.isValid = d => !isNaN(Date.parse(d));

1
MDN'den: "Date.parse () yöntemi, bir tarihin dize olarak temsilini ayrıştırır ve 1 Ocak 1970, 00:00:00 UTC veya NaN'den bu yana milisaniye sayısını döndürür." Bu nedenle, potansiyel bir tarihi çalıştırmak işlevi bir tamsayı veya NaN döndürür. Daha sonra isNaN () işlevi, orijinal değerin geçerli bir tarih nesnesi olup olmadığını söyleyen temiz bir boole verecektir. Bu, bir nokta kontrolü yapmak için yeterlidir, ancak yukarıdaki örnek, işlevselliği programınız boyunca kolayca kullanılabilir ve okunabilir hale getirmek için bu yöntemi Date nesnesine ekler.
Max Wilder

d boolean ise, Nan olmayan 0 veya 1 alırsınız !!
davcup

@davcup kullanarak test Date.parse(true), doğru bir NaN alıyorum.
Sebastien H.

12

Bu küçük pasaja yaklaşan bazı cevaplar gördüm.

JavaScript yolu:

function isValidDate(dateObject){ return new Date(dateObject).toString() !== 'Invalid Date'; }
isValidDate(new Date('WTH'));

TypeScript yolu:

const isValidDate = dateObject => new Date(dateObject ).toString() !== 'Invalid Date';
isValidDate(new Date('WTH'));

1
Bir şey eksik olup olmadığımdan emin değilim ama iki kez anlamsız yeni Date () yapmıyor musunuz?
Jon Catmull

2
İkincisi sahiptir şey typescript ile ilgisi yok. Tamamen geçerli bir JS.
hackel

9

Güzel çözüm! Yardımcı fonksiyonlar kütüphaneme dahil, şimdi şöyle görünüyor:

Object.isDate = function(obj) {
/// <summary>
/// Determines if the passed object is an instance of Date.
/// </summary>
/// <param name="obj">The object to test.</param>

    return Object.prototype.toString.call(obj) === '[object Date]';
}

Object.isValidDate = function(obj) {
/// <summary>
/// Determines if the passed object is a Date object, containing an actual date.
/// </summary>
/// <param name="obj">The object to test.</param>

    return Object.isDate(obj) && !isNaN(obj.getTime());
}

9

Bu benim için çalıştı

new Date('foo') == 'Invalid Date'; //is true

Ancak bu işe yaramadı

new Date('foo') === 'Invalid Date'; //is false

5
Bunun tarayıcıya bağlı olduğuna inanıyorum.
barrypicker

@barrypicker Ne demek bu tarayıcıya bağlı?
Ajil O.

Şunları yapabilirsiniz: `${new Date('foo')}` === 'Invalid Date'
Daniele Vrut

9

Angular.js projeleri için şunları kullanabilirsiniz:

angular.isDate(myDate);

3
Geçersiz Tarih ile başlatılmış bir tarih nesnesi test edilirken bu değer true değerini döndürür.
dchhetri

6

31.02.2012 gibi bir tarihi doğrulamaya çalışırken bu yanıtların hiçbiri benim için (Safari 6.0'da test edildi) işe yaramadı, ancak 31'den büyük herhangi bir tarihi denerken iyi çalışıyorlar.

Bu yüzden biraz güç harcamam gerekiyordu. Tarihin formatta olduğu varsayılarak mm/dd/yyyy. @Broox cevap kullanıyorum:

Date.prototype.valid = function() {
    return isFinite(this);
}    

function validStringDate(value){
    var d = new Date(value);
    return d.valid() && value.split('/')[0] == (d.getMonth()+1);
}

validStringDate("2/29/2012"); // true (leap year)
validStringDate("2/29/2013"); // false
validStringDate("2/30/2012"); // false

(yeni Tarih ('2/30/2014')). geçerli () true değerini döndürür
Andre Figueiredo

1
Bunu cevapladığımdan bu yana bir süre geçirdim, ancak&& value.split('/')[0] == (d.getMonth()+1);
Dex

Kullanmak new Date('string date')ile eşdeğerdir Date.parse('string date'), bkz: developer.mozilla.org/tr-TR/docs/Web/JavaScript/Reference/… böylece yanlış doğru veya yanlış değerler elde edebilirsiniz.
golddragon007

5

Yukarıdaki çözümlerin hiçbiri benim için işe yaramadı, ancak ne işe yaradı?

function validDate (d) {
        var date = new Date(d);
        var day = ""+date.getDate();
        if( day.length == 1)day = "0"+day;
        var month = "" +( date.getMonth() + 1);
        if( month.length == 1)month = "0"+month;
        var year = "" + date.getFullYear();

        return ((month + "/" + day + "/" + year) == d);
    }

yukarıdaki kod, JS'nin 02.02.2012 ile 03/02/2012 tarihine kadar geçerli olmadığını gördüğünde


3
Tamam, ancak bu, bir dizenin "geçerli ve geçersiz tarih nesneleri arasındaki fark" değil, M / D / Y biçimindeki bir tarih olup olmadığını test eder. Bunun ne hakkında olduğu gerçekten değil.
Borgar

biçimine karşı kontrol edilmesinin nedeni, ayrıştırıldıktan sonra tarihin değişip değişmediğini kontrol etmektir
John

OP, biçimlendirilmiş bir dize değil, bir Boole döndürmek için bir yöntem istemiyor mu?
barrypicker

1
Örnek kod bir boole döndürür, biçimlendirme bazı geçersiz durumlar için testte rol oynar.
John

5
IsValidDate: function(date) {
        var regex = /\d{1,2}\/\d{1,2}\/\d{4}/;
        if (!regex.test(date)) return false;
        var day = Number(date.split("/")[1]);
        date = new Date(date);
        if (date && date.getDate() != day) return false;
        return true;
}

4

Bu işlevi yazdım. Bir string parametresi iletin ve bu "dd / AA / yyyy" biçimini temel alarak geçerli bir tarih olup olmadığını belirler.

işte bir test

girdi: "hahaha", çıktı: yanlış.

girdi: "29/2/2000", çıktı: doğru.

girdi: "29/2/2001", çıktı: yanlış.

function isValidDate(str) {
    var parts = str.split('/');
    if (parts.length < 3)
        return false;
    else {
        var day = parseInt(parts[0]);
        var month = parseInt(parts[1]);
        var year = parseInt(parts[2]);
        if (isNaN(day) || isNaN(month) || isNaN(year)) {
            return false;
        }
        if (day < 1 || year < 1)
            return false;
        if(month>12||month<1)
            return false;
        if ((month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) && day > 31)
            return false;
        if ((month == 4 || month == 6 || month == 9 || month == 11 ) && day > 30)
            return false;
        if (month == 2) {
            if (((year % 4) == 0 && (year % 100) != 0) || ((year % 400) == 0 && (year % 100) == 0)) {
                if (day > 29)
                    return false;
            } else {
                if (day > 28)
                    return false;
            }      
        }
        return true;
    }
}

4

Date.prototype.toISOStringRangeErrorgeçersiz tarihlerde atar (en azından Chromium ve Firefox'ta). Doğrulama aracı olarak kullanabilirsiniz ve bu şekilde gerekmeyebilir isValidDate(EAFP). Aksi takdirde:

function isValidDate(d)
{
  try
  {
    d.toISOString();
    return true;
  }
  catch(ex)
  {
    return false;    
  }    
}

1
ECMA-262 tanımıyla hata veren tek işlev gibi görünüyor. 15.9.5.43 Date.prototype.toISOString () Bu işlev, bu Date nesnesi tarafından temsil edilen zamanı temsil eden bir String değeri döndürür. Dize biçimi, 15.9.1.15'te tanımlanan Tarih Saati dize biçimidir. Dize'de tüm alanlar bulunur. Saat dilimi her zaman UTC'dir ve Z son ekiyle gösterilir. Bu nesnenin saat değeri sınırlı bir Sayı değilse, bir RangeError istisnası atılır.
Henry Liu

3

Borgar'ın yaklaşımından esinlenerek kodun sadece tarihi doğrulamakla kalmayıp, aynı zamanda tarihin gerçek bir tarih olmasını da sağladım, yani 31/09/2011 ve 29/02/2011 gibi tarihlere izin verilmiyor.

function(dateStr) {
    s = dateStr.split('/');
    d = new Date(+s[2], s[1]-1, +s[0]);
    if (Object.prototype.toString.call(d) === "[object Date]") {
        if (!isNaN(d.getTime()) && d.getDate() == s[0] && 
            d.getMonth() == (s[1] - 1)) {
            return true;
        }
    }
    return "Invalid date!";
}

Ancak ... yukarıdaki yöntemler (@ Borgar'ın ve diğerlerinin) zaten bu tür geçerliliği kontrol ediyor ... Sorunu alamıyorum.
mavimsi

Borgar'ın cevabı - kendi yorumunu görmüyor.
EML

1
Bu çözüm yalnızca ülkeniz dd/MM/yyyygösterimi kullandığında çalışır . Ayrıca, truegeçerli olduğunda döner ve 'Invalid date!'eğer değilse, sadece 1 tipini döndürmeniz daha iyi olur.
A1rPun

3

Belirli bir nesne olup olmadığını kontrol ettiğimde bulduğum en iyi performans sonuçlarını birleştirdim:

Sonuç şudur:

function isValidDate(input) {
  if(!(input && input.getTimezoneOffset && input.setUTCFullYear))
    return false;

  var time = input.getTime();
  return time === time;
};

2

Dizeye tarih nesnesi, her iki alanın da geçerli tarih olup olmadığını tespit etmenin daha basit ve güvenilir bir yoludur. Örneğin, tarih giriş alanına "-------" girerseniz. Yukarıdaki cevaplardan bazıları işe yaramaz.

jQuery.validator.addMethod("greaterThan", 

    function(value, element, params) {
        var startDate = new Date($(params).val());
        var endDate = new Date(value);

        if(startDate.toString() === 'Invalid Date' || endDate.toString() === 'Invalid Date') {
            return false;
        } else {
            return endDate > startDate;
        }
    },'Must be greater than {0}.');

2

Seçilen cevap mükemmel ve ben de kullanıyorum. Ancak, kullanıcı tarihi girişini doğrulamanın bir yolunu arıyorsanız, Date nesnesinin geçersiz inşaat bağımsız değişkenleri gibi görünen şeyleri geçerli olanlara dönüştürmede çok kalıcı olduğunu bilmelisiniz. Aşağıdaki birim test kodu noktayı gösterir:

QUnit.test( "valid date test", function( assert ) {
  //The following are counter-examples showing how the Date object will 
  //wrangle several 'bad' dates into a valid date anyway
  assert.equal(isValidDate(new Date(1980, 12, 15)), true);
  d = new Date();
  d.setFullYear(1980);
  d.setMonth(1);
  d.setDate(33);
  assert.equal(isValidDate(d), true);
  assert.equal(isValidDate(new Date(1980, 100, 150)), true);
  //If you go to this exterme, then the checker will fail
  assert.equal(isValidDate(new Date("This is junk")), false);
  //This is a valid date string
  assert.equal(isValidDate(new Date("November 17, 1989")), true);
  //but is this?
  assert.equal(isValidDate(new Date("November 35, 1989")), false);  
  //Ha!  It's not.  So, the secret to working with this version of 
  //isValidDate is to pass in dates as text strings... Hooboy
  //alert(d.toString());
});

2
function isValidDate(strDate) {
    var myDateStr= new Date(strDate);
    if( ! isNaN ( myDateStr.getMonth() ) ) {
       return true;
    }
    return false;
}

Buna şöyle deyin

isValidDate(""2015/5/2""); // => true
isValidDate(""2015/5/2a""); // => false

2

En yüksek puan alan cevaba dayalı hazır bir fonksiyon:

  /**
   * Check if date exists and is valid.
   *
   * @param {String} dateString Date in YYYY-mm-dd format.
   */
  function isValidDate(dateString) {
  var isValid = false;
  var date;

  date =
    new Date(
      dateString);

  if (
    Object.prototype.toString.call(
      date) === "[object Date]") {

    if (isNaN(date.getTime())) {

      // Date is unreal.

    } else {
      // Date is real if month and day match each other in date and string (otherwise may be shifted):
      isValid =
        date.getUTCMonth() + 1 === dateString.split("-")[1] * 1 &&
        date.getUTCDate() === dateString.split("-")[2] * 1;
    }
  } else {
    // It's not a date.
  }

  return isValid;
}

2

Basit ve zarif bir çözüm:

const date = new Date(`${year}-${month}-${day} 00:00`)
const isValidDate = (Boolean(+date) && date.getDate() == day)

kaynaklar:

[1] https://medium.com/@esganzerla/simple-date-validation-with-javascript-caea0f71883c

[2] JavaScript'te yeni Date () ile yanlış tarih gösteriliyor


1
date.getDate() == daytarihin geçerli olup olmadığını belirlemek için yetersizdir. Orijinal tarih biçimi, tarihin geçerli olup olmadığına bakılmaksızın bazı uygulamalarda geçersiz bir tarih döndürür. Ayrıca doğru şekilde ayrıştırılırsa "1970-01-01 00:00" yanlış Boolean(+new Date("1970-01-01"))döndürür (yani yanlış döndürür).
RobG

UYARI: Safari'de çalışmaz
Vigrant

Biçimi kullanırsanız Safari'de çalışır. const date = new Date(year, month, day); Ayın bu şekilde dizine eklendiğini unutmayın, böylece doğru şekilde hizalamak için birini çıkarmanız gerekebilir.
Vigrant

1

Bence bunlardan bazıları uzun bir süreç. Aşağıda gösterildiği gibi kısa kesebiliriz:

 function isValidDate(dateString) {
        debugger;
        var dateStringSplit;
        var formatDate;

        if (dateString.length >= 8 && dateString.length<=10) {
            try {
                dateStringSplit = dateString.split('/');
                var date = new Date();
                date.setYear(parseInt(dateStringSplit[2]), 10);
                date.setMonth(parseInt(dateStringSplit[0], 10) - 1);
                date.setDate(parseInt(dateStringSplit[1], 10));

                if (date.getYear() == parseInt(dateStringSplit[2],10) && date.getMonth()+1 == parseInt(dateStringSplit[0],10) && date.getDate() == parseInt(dateStringSplit[1],10)) {
                    return true;
                }
                else {
                    return false;
                }

            } catch (e) {
                return false;
            }
        }
        return false;
    }

3
Soru, dizelerin değil, geçersiz Tarih örneklerinin nasıl bulunacağını sordu: Bir tarih, eğik çizgi dışında bir şeyle sınırlanamayacağını kim söylüyor?
Jon z

1

Bir tarihin int 1 tabanlı bileşenleri için:

var is_valid_date = function(year, month, day) {
    var d = new Date(year, month - 1, day);
    return d.getFullYear() === year && (d.getMonth() + 1) === month && d.getDate() === day
};

Testler:

    is_valid_date(2013, 02, 28)
&&  is_valid_date(2016, 02, 29)
&& !is_valid_date(2013, 02, 29)
&& !is_valid_date(0000, 00, 00)
&& !is_valid_date(2013, 14, 01)
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.