Erkennen einer Datumsinstanz mit ungültigem Datum in JavaScript


1494

Ich möchte den Unterschied zwischen gültigen und ungültigen Datumsobjekten in JS feststellen, konnte aber nicht herausfinden, wie:

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'

Irgendwelche Ideen zum Schreiben einer isValidDateFunktion?

  • Ash wird Date.parsezum Parsen von Datumszeichenfolgen empfohlen. Auf diese Weise können Sie überprüfen, ob die Datumszeichenfolge gültig ist.
  • Wenn möglich, würde ich es vorziehen, wenn meine API eine Datumsinstanz akzeptiert und prüfen / bestätigen kann, ob sie gültig ist oder nicht. Borgars Lösung macht das, aber ich muss es browserübergreifend testen. Ich frage mich auch, ob es einen eleganteren Weg gibt.
  • Ash ließ mich überlegen, ob meine API überhaupt keine DateInstanzen akzeptieren sollte. Dies wäre am einfachsten zu überprüfen.
  • Borgar schlug vor, eine DateInstanz zu testen und dann den DateZeitwert der Instanz zu testen . Wenn das Datum ungültig ist, ist der Zeitwert NaN. Ich habe mit ECMA-262 nachgefragt und dieses Verhalten ist im Standard enthalten, genau das, wonach ich suche.

18
Sie können die if-Anweisung entfernen, indem Sie den Hauptteil der Funktion in:return ( Object.prototype.toString.call(d) === "[object Date]" && !isNaN(d.getTime()) );
styfle

3
@styfle - denke, es ist eine Stilvorliebe: Ich finde es klarer, die Typprüfung von der Gleichheitslogik zu trennen.
Orip

26
@ orip Diskurs ist genau das, was in Fragen stark entmutigt wird. Bitte beziehen Sie sich auf relevante Metathemen, um die Gründe dafür zu erfahren. Das Platzieren einer Antwort auf die eigene Frage in der Frage selbst verstößt gegen die Site-Richtlinie. OTOH, sich für die Antworten zu bedanken und "EDIT" in Ihrer Antwort zu haben, ist ein typischer Flaum. Wenn Sie möchten, dass Ihre bestbewertete Frage Sie als eine Person identifiziert, die nicht weiß, was SO ist und wie man es verwendet, und das nicht lernen möchte - seien Sie mein Gast.

14
@orip: Es war nicht "verloren"; Der Revisionsverlauf der Frage ist immer noch unübersichtlich, wenn Sie ihn erneut anzeigen möchten. Aber es gehört nicht in eine Frage. Bei 37.000 Wiederholungen sollten Sie dies wissen.
Leichtigkeitsrennen im Orbit

6
Bitte stoppen Sie den Editierkrieg. Die Änderungen an dieser Frage werden auf Meta diskutiert . Bitte bearbeiten / rollen Sie diesen Beitrag nicht weiter. Wenn Sie mit früheren Änderungen / Rollbacks nicht einverstanden sind oder Kommentare dazu haben, posten Sie diese bitte in diesem Meta-Thread und nicht hier.
Lundin

Antworten:


1302

So würde ich es machen:

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
}

Update [2018-05-31] : Wenn Sie sich nicht mit Datumsobjekten aus anderen JS-Kontexten (externen Fenstern, Frames oder Iframes) befassen, wird diese einfachere Form möglicherweise bevorzugt:

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

21
Instanz von Unterbrechungen über Frames hinweg. Das Enten-Tippen kann auch gut funktionieren: validDate == d && d.getTime &&! IsNaN (d.getTime ()); - Da es sich um eine allgemeine Utility-Funktion handelt, bin ich lieber strenger.
Borgar

11
@Borgar, habe gerade meine Antwort gefunden: "Die Probleme treten auf, wenn es um die Skripterstellung in DOM-Umgebungen mit mehreren Frames geht. Kurz gesagt, Array-Objekte, die in einem Iframe erstellt wurden, teilen [[Prototype]] nicht mit Arrays, die in einem anderen Iframe erstellt wurden Ihre Konstruktoren sind unterschiedliche Objekte, sodass sowohl Instanz- als auch Konstruktorprüfungen fehlschlagen. "
Ash

64
Sie brauchen nicht einmal d.getTimenurisNan(d)
TecHunter

8
Könnte so vereinfacht werden:d instanceof Date && !isNaN(d.getTime())
Zorgatone

5
Vielen Dank für die Antwort, aber ich möchte die Kommentare von @Borgar und @blueprintChris hervorheben: Wenn ich 1zum Beispiel die Ziffer analysiere, hätte ich immer noch ein gültiges Datum, Mon Jan 01 2001 00:00:00das tatsächlich ein Datum ist, aber für den Zweck meiner Anwendung ist es völlig nutzlos . Daher ist zumindest in meinem Fall eine weitere Eingabevalidierung erforderlich. Diese Antwort bestätigt ein dateObjectnicht ein Date!
Dnhyd

264

Anstatt zu verwenden new Date(), sollten Sie verwenden:

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

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

Date.parse()Gibt einen Zeitstempel zurück, eine Ganzzahl, die die Anzahl der Millisekunden seit dem 01. Januar 1970 angibt. Es wird zurückgegeben, NaNwenn die angegebene Datumszeichenfolge nicht analysiert werden kann.


119
-1 Keine Ahnung, warum dies so viele Up-Votes hat, Date.parseist implementierungsabhängig und definitiv nicht vertrauenswürdig, um allgemeine Datumszeichenfolgen zu analysieren. Es gibt kein einzelnes Format, das in gängigen Browsern korrekt analysiert wird, geschweige denn alle verwendeten (obwohl das in ES5 angegebene ISO8601-Format möglicherweise in Ordnung sein sollte).
RobG

1
Wenn Sie das verwenden new Date('foo'), entspricht dies im Wesentlichen der Date.parse('foo')Methode. Siehe: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… Was @RobG gesagt hat, gilt auch dafür.
Golddragon007

2
Dieser Test würde in Chrome fehlschlagen. Zum Beispiel gibt mir Date.parse ('AAA-0001') in Chrome eine Nummer.
Nick

fehlgeschlagen ... alle numerischen Werte erkennen
Hos Mercury

109

Sie können die Gültigkeit eines DateObjekts düber überprüfen

d instanceof Date && isFinite(d)

Um rahmenübergreifende Probleme zu vermeiden, könnte man die instanceofPrüfung durch ersetzen

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

Ein Aufruf getTime()wie in Borgar Antwort ist nicht notwendig , da isNaN()und isFinite()beide konvertieren implizit Nummer.


Versuchen Sie dies in Chrome - Object.prototype.toString.call (neues Datum ("2013-07-09T19: 07: 9Z")). Es wird "[Objektdatum]" zurückgegeben. Ihrer Meinung nach sollte "2013-07-09T19: 07: 9Z" daher ein gültiges Datum sein. Aber es ist nicht. Sie können dies erneut in Chrome überprüfen, indem Sie var dateStr = new Date ("2013-07-09T19: 07: 9Z") ausführen. dateStr Es wird ein ungültiges Datum zurückgegeben.
Tim und Struppi

2
@ Tim und Struppi: das ist, was isFinite()ist - toString.call()ist nur ein Ersatz für den instanceofTeil des Schecks
Christoph

Funktioniert der Vergleich mit '[Objektdatum]' mit nicht englischen Browsern? Ich bezweifle das.
Kristianp

2
@kristianp tatsächlich wird es wahrscheinlich und ist wahrscheinlich sogar Teil der ECMAScript-Spezifikation. Aber ja, es scheint hässlich.
Binki

Für mich ist der erste Ansatz hier die beste Option, obwohl ich nicht sicher bin, ob es einen echten Vorteil der Verwendung von isFiniteOver gibt isNaN(beide funktionieren einwandfrei Date(Infinity)). Wenn Sie die entgegengesetzte Bedingung wünschen, wird es außerdem etwas einfacher : if (!(date instanceof Date) || isNaN(date)).
Andrew

86

Meine Lösung besteht darin, einfach zu überprüfen, ob Sie ein gültiges Datumsobjekt erhalten:

Implementierung

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

Verwendungszweck

var d = new Date("lol");

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

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

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

28
isNaNist eine explizitere Möglichkeit, um NaN
orip

1
Und doch finden Sie immer Leute, die ihre eigenen Versionen schreiben :) documentcloud.github.com/underscore/docs/…
Ash Clarke

4
da ich underscore.js respektiere, veranlasste dies einige Nachforschungen. isNaN("a") === truewährend ("a" !== "a") === false. Es lohnt sich darüber nachzudenken. +1
Orip

8
Ich habe die Leistung für die 3 Hauptlösungen getestet, die ich hier gefunden habe. Herzlichen Glückwunsch, Sie sind der Gewinner! jsperf.com/detecting-an-invalid-date
zVictor

2
@Ali Das ist ein gültiges Datumsobjekt. new Date("02-31-2000") // Thu Mar 02 2000 00:00:00 GMT+0000 (GMT Standard Time). Wenn Sie eine Zeichenfolge an den Datumskonstruktor übergeben, müssen Sie eine standardisierte Zeichenfolge übergeben, um ein zuverlässiges Ergebnis zu erhalten. Insbesondere "Die Zeichenfolge sollte in einem Format vorliegen, das von der Date.parse () -Methode erkannt wird". developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Ash Clarke

71

kürzeste Antwort, um das gültige Datum zu überprüfen

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

2
Das einzige Problem ist, wenn das Datum nicht vom Typ Datum ist. Sie erhalten einen JS-Fehler.
Andrew

@ Andrew Sie müssen das Datum Objekt erstellen und wenn Sie bereits ein Objekt haben, dann verwenden Siedate && !isNaN(date.getTime())
abhirathore2006

Das gibt Ihnen immer noch einen JS-Fehler, wenn er datenicht vom Typ Datum ist. Zum Beispiel : var date = 4; date && !isNaN(date.getTime());.
Andrew

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

3
Richtig, wie die anderen Antworten von vor 8 Jahren. : P stackoverflow.com/a/1353945/2321042
Andrew

45

Sie können einfach moment.js verwenden

Hier ist ein Beispiel:

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

Der Validierungsabschnitt in der Dokumentation ist ziemlich klar.

Außerdem führen die folgenden Analyseflags zu einem ungültigen Datum:

  • overflow: Ein Überlauf eines Datumsfelds, z. B. ein 13. Monat, ein 32. Tag des Monats (oder ein 29. Februar bei Nicht-Schaltjahren), ein 367. Tag des Jahres usw. Überlauf enthält den Index der ungültigen Einheit um mit #invalidAt übereinzustimmen (siehe unten); -1 bedeutet kein Überlauf.
  • invalidMonth: Ein ungültiger Monatsname, z. B. Moment ('Marbruary', 'MMMM');. Enthält die ungültige Monatszeichenfolge selbst oder null.
  • empty: Eine Eingabezeichenfolge, die nichts Analysierbares enthält, wie z. B. Moment ('das ist Unsinn');. Boolescher Wert.
  • Usw.

Quelle: http://momentjs.com/docs/


6
Die beste Lösung, die extrem einfach zu implementieren ist, funktioniert mit jeder Formatierung (mein Fall ist TT / MM / JJJJ), kennt auch die Schaltjahre und konvertiert ungültige Daten (dh 29.02.2015) nicht selbst in gültige (dh 30/03/2015). Um ein Datum in der Form TT / MM / JJJJ zu überprüfen, musste ich nur verwendenmoment("11/06/1986", "DD/MM/YYYY").isValid();
Rafael Merlin

3
Diese Verwendung von Moment ist veraltet :(
James Sumners

2
Diese Verwendung wurde nicht abgeschrieben. Der Aufrufzeitpunkt (Eingabe) ohne Formatzeichenfolge wird abgeschrieben (es sei denn, die Eingabe ist ISO-formatiert).
Chet

2
Diese Methode kann bei der Verarbeitung vieler Daten extrem langsam sein. Verwenden Sie in diesen Fällen besser einen regulären Ausdruck.
Grid Trekkor

2
Die Verwendung von moment.js mag einfach sein, ist aber ein enormer Aufwand. Diese Bibliothek ist riesig. Ich habe deine Antwort abgelehnt.
Mick

38

Ich möchte erwähnen, dass das jQuery UI DatePicker-Widget über eine sehr gute Datumsüberprüfungs-Dienstprogrammmethode verfügt, die das Format und die Gültigkeit überprüft (z. B. keine Datumsangaben vom 03.01.2013 zulässig).

Auch wenn Sie das Datepicker-Widget auf Ihrer Seite nicht als UI-Element verwenden möchten, können Sie die .js-Bibliothek jederzeit zu Ihrer Seite hinzufügen und dann die Validator-Methode aufrufen und den zu validierenden Wert übergeben. Um das Leben noch einfacher zu machen, wird eine Zeichenfolge als Eingabe verwendet, kein JavaScript-Datumsobjekt.

Siehe: http://api.jqueryui.com/datepicker/

Es ist nicht als Methode aufgeführt, aber es ist da - als Dienstprogrammfunktion. Durchsuchen Sie die Seite nach "parsedate" und Sie werden finden:

$ .datepicker.parseDate (Format, Wert, Einstellungen) - Extrahieren Sie ein Datum aus einem Zeichenfolgenwert mit einem angegebenen Format.

Anwendungsbeispiel:

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

(Weitere Informationen zur Angabe von Datumsformaten finden Sie unter http://api.jqueryui.com/datepicker/#utility-parseDate )

Im obigen Beispiel wird die Warnmeldung nicht angezeigt, da '01 / 03/2012 'ein kalendergültiges Datum im angegebenen Format ist. Wenn Sie beispielsweise 'stringval' gleich '13 / 04/2013 'gemacht haben, wird die Warnmeldung angezeigt, da der Wert '13 / 04/2013' nicht für den Kalender gültig ist.

Wenn ein übergebener Zeichenfolgenwert erfolgreich analysiert wurde, ist der Wert von 'testdate' ein Javascript Date-Objekt, das den übergebenen Zeichenfolgenwert darstellt. Wenn nicht, wäre es undefiniert.


3
Upvote für die erste Antwort, die mit Datumsformaten außerhalb von Englisch / Gebietsschema arbeitet.
Axt.

26

Ich mochte Christophs Ansatz sehr (hatte aber nicht genug Ruf, um darüber abzustimmen). Ich weiß, dass ich immer ein Date-Objekt haben werde, also habe ich das Datum nur mit einer valid () -Methode erweitert.

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

Jetzt kann ich das einfach schreiben und es ist viel aussagekräftiger als nur das Überprüfen von isFinite im Code ...

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

10
Prototyp erweitern? Das ist ein großes JavaScript nein nein!
Jasdeep Khalsa

Upvoting wegen der isFinitefür mich perfekt funktionierenden. Aber ja, es ist sinnlos, den Prototyp zu erweitern. !isFiniteauf einen DateWillen fangen die Tatsache, dass das Dateist Invalid Date. Erwähnenswert ist auch, dass sich mein Kontext in Node befindet.
Staghouse

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

5
Es ist das gleiche, was @Borgar vor 2 Jahren geschrieben hat ... Was ist neu?
bläulich

11
Es sind zwei Zeilen anstelle von hässlich verschachtelten if-Anweisungen.
Cypher

17

Mit diesem Scirpt können Sie das gültige Format von txDate.value überprüfen. Wenn es im falschen Format war, wurde das Datumsobjekt nicht instanziiert und es wurde null an dt zurückgegeben.

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

Und wie @ MiF's kurz vorgeschlagen hat

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

isNaN (neues Datum (...)) - die einfache und kurze Methode
MiF

1
@ MiF ja, ich aktualisiere meine Antwort mit Ihrem Vorschlag;) danke
Yuseferi

16

Ich verwende den folgenden Code, um Werte für Jahr, Monat und Datum zu validieren.

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

Weitere Informationen finden Sie unter Überprüfen des Datums in Javascript


strwird nicht verwendet.
Samis

12

Hier gibt es bereits zu viele komplizierte Antworten, aber eine einfache Zeile reicht aus (ES5):

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

oder sogar in ES6:

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

1
Von MDN: "Die Date.parse () -Methode analysiert eine Zeichenfolgendarstellung eines Datums und gibt die Anzahl der Millisekunden seit dem 1. Januar 1970, 00:00:00 UTC oder NaN ... zurück." Die Funktion gibt entweder eine Ganzzahl oder NaN zurück. Dann gibt die Funktion isNaN () einen sauberen Booleschen Wert aus, der Ihnen sagt, ob der ursprüngliche Wert ein gültiges Datumsobjekt war oder nicht. Dies reicht aus, um eine Stichprobe durchzuführen. Im obigen Beispiel wird diese Methode dann an das Date-Objekt angehängt, um die Funktionalität in Ihrem gesamten Programm leicht verfügbar und lesbar zu machen.
Max Wilder

Wenn d boolesch ist, erhalten Sie 0 oder 1, die keine Nan ist !!
Davcup

@davcup gerade getestet mit Date.parse(true), bekomme ich richtig eine NaN.
Sebastien H.

12

Ich habe einige Antworten gesehen, die diesem kleinen Ausschnitt sehr nahe kamen.

JavaScript-Methode:

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

TypeScript-Methode:

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

1
Sie sind sich nicht sicher, ob ich etwas vermisse, aber ist es nicht sinnlos, ein neues Date () zweimal zu machen?
Jon Catmull

2
Letzteres hat nichts mit TypeScript zu tun. Es ist vollkommen gültig JS.
Hackel

9

Schöne Lösung! In meiner Bibliothek mit Hilfsfunktionen enthalten, sieht es jetzt so aus:

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

Das hat gerade bei mir funktioniert

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

Dies hat jedoch nicht funktioniert

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

5
Ich glaube, das ist browserabhängig.
Barrypicker

@barrypicker Was meinst du damit, dass dies browserabhängig ist?
Ajil O.

Sie können tun: `${new Date('foo')}` === 'Invalid Date'
Daniele Vrut

9

Für Angular.js-Projekte können Sie Folgendes verwenden:

angular.isDate(myDate);

3
Dies gibt true zurück, wenn ein Datumsobjekt getestet wird, das mit einem ungültigen Datum initialisiert wurde.
Dchhetri

6

Keine dieser Antworten funktionierte für mich (getestet in Safari 6.0), wenn ich versuchte, ein Datum wie den 31.02.2012 zu validieren. Sie funktionieren jedoch einwandfrei, wenn ich ein Datum größer als 31 versuche.

Also musste ich ein wenig brutale Gewalt anwenden. Angenommen, das Datum hat das Format mm/dd/yyyy. Ich benutze @broox Antwort:

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

(neues Datum ('30.02.2014')). valid () gibt true zurück
Andre Figueiredo

1
Es ist schon eine Weile her, seit ich darauf geantwortet habe, aber Sie benötigen möglicherweise beide Rückgabebedingungen, einschließlich der&& value.split('/')[0] == (d.getMonth()+1);
Dex

Die Verwendung new Date('string date')ist gleichbedeutend mit Date.parse('string date'): developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…, sodass Sie möglicherweise falsche wahre oder falsche Werte erhalten.
Golddragon007

5

Keine der oben genannten Lösungen hat bei mir funktioniert, was jedoch funktioniert hat

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

Der obige Code wird sehen, wenn JS den 31.02.2012 zum 02.03.2012 macht, dass er nicht gültig ist


3
Ok, aber dies testet, ob eine Zeichenfolge ein Datum in einem M / D / Y-Format ist, nicht "der Unterschied zwischen gültigen und ungültigen Datumsobjekten". Es ist nicht wirklich das, worum es hier geht.
Borgar

Der Grund, warum es mit dem Format verglichen wird, ist zu überprüfen, ob sich das Datum geändert hat, nachdem es analysiert wurde
John

Fordert das OP nicht eine Methode zur Rückgabe eines Booleschen Werts an, keine formatierte Zeichenfolge?
Barrypicker

1
Der Beispielcode gibt einen Booleschen Wert zurück. Die Formatierung spielt beim Testen auf einige der ungültigen Fälle eine Rolle.
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

Ich habe diese Funktion geschrieben. Übergeben Sie ihm einen String-Parameter und er bestimmt anhand dieses Formats "TT / MM / JJJJ", ob es sich um ein gültiges Datum handelt oder nicht.

Hier ist ein Test

Eingabe: "hahaha", Ausgabe: false.

Eingabe: "29/2/2000", Ausgabe: true.

Eingabe: "29/2/2001", Ausgabe: false.

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.toISOStringwirft RangeError(zumindest in Chromium und Firefox) auf ungültige Daten. Sie können es als Validierungsmittel verwenden und benötigen es möglicherweise nicht isValidDateals solches (EAFP). Ansonsten ist es:

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

1
Es scheint, dass dies die einzige Funktion ist, die einen Fehler gemäß ECMA-262-Definition auslöst. 15.9.5.43 Date.prototype.toISOString () Diese Funktion gibt einen String-Wert zurück, der die durch dieses Date-Objekt dargestellte Instanz in der Zeit darstellt. Das Format der Zeichenfolge ist das in 15.9.1.15 definierte Datums- / Uhrzeitzeichenfolgenformat. Alle Felder sind in der Zeichenfolge vorhanden. Die Zeitzone ist immer UTC, gekennzeichnet durch das Suffix Z. Wenn der Zeitwert dieses Objekts keine endliche Zahl ist, wird eine RangeError-Ausnahme ausgelöst.
Henry Liu

3

Inspiriert von Borgars Ansatz habe ich sichergestellt, dass der Code nicht nur das Datum validiert, sondern auch sicherstellt, dass das Datum ein echtes Datum ist, was bedeutet, dass Daten wie der 31.09.2011 und der 29.02.2011 nicht zulässig sind.

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

Aber ... die oben genannten Methoden (@ Borgar's und die anderen) prüfen bereits auf diese Art der Gültigkeit ... Ich kann das Problem nicht verstehen.
bläulich

Borgars nicht - siehe seinen eigenen Kommentar zu seiner Antwort.
EML

1
Diese Lösung funktioniert nur, wenn Ihr Land die dd/MM/yyyyNotation verwendet. Außerdem wird es zurückgegeben, truewenn es gültig ist. 'Invalid date!'Wenn dies nicht der Fall ist, geben Sie besser nur 1 Typ zurück.
A1rPun

3

Ich habe die besten Leistungsergebnisse kombiniert, die ich bei dieser Prüfung gefunden habe, wenn ein bestimmtes Objekt:

Das Ergebnis ist folgendes:

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

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

2

Datumsobjekt zu Zeichenfolge ist einfacher und zuverlässiger, um festzustellen, ob beide Felder ein gültiges Datum sind. zB Wenn Sie dieses "-------" in das Datumseingabefeld eingeben. Einige der oben genannten Antworten funktionieren nicht.

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

Die ausgewählte Antwort ist ausgezeichnet und ich verwende sie auch. Wenn Sie jedoch nach einer Möglichkeit suchen, die Eingabe von Benutzerdaten zu überprüfen, sollten Sie sich darüber im Klaren sein, dass das Date-Objekt sehr hartnäckig ist, wenn es darum geht, scheinbar ungültige Konstruktionsargumente in gültige Argumente umzuwandeln. Der folgende Unit-Test-Code veranschaulicht den Punkt:

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

Nennen Sie es so

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

2

Eine fertige Funktion basierend auf der am besten bewerteten Antwort:

  /**
   * 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

Einfache und elegante Lösung:

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

Quellen:

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

[2] Falsches Datum in neuem Datum () in JavaScript angezeigt


1
date.getDate() == dayreicht nicht aus, um festzustellen, ob das Datum gültig ist. Das ursprüngliche Datumsformat gibt in einigen Implementierungen ein ungültiges Datum zurück, unabhängig davon, ob das Datum gültig ist oder nicht. Auch "1970-01-01 00:00" gibt bei korrekter Analyse false zurück (dh Boolean(+new Date("1970-01-01"))gibt false zurück).
RobG

WARNUNG: Dies funktioniert nicht in Safari
Vigrant

Es funktioniert in Safari, wenn Sie das Format verwenden. const date = new Date(year, month, day); Beachten Sie, dass der Monat auf diese Weise 0 indiziert ist, sodass Sie möglicherweise einen subtrahieren müssen, um ihn korrekt auszurichten.
Vigrant

1

Ich denke, einiges davon ist ein langer Prozess. Wir können es wie unten gezeigt abkürzen:

 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
Die Frage lautete, wie ungültige Datumsinstanzen und keine Zeichenfolgen gefunden werden können. Außerdem: Wer sagt, dass ein Datum nicht durch einen anderen Schrägstrich begrenzt werden kann?
Jon z

1

Für int 1-basierte Komponenten eines Datums:

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

Tests:

    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)
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.