Überprüfen Sie, ob eine Zeichenfolge ein Datumswert ist

207

Was ist eine einfache Möglichkeit, um zu überprüfen, ob ein Wert ein gültiges Datum ist, wobei jedes bekannte Datumsformat zulässig ist.

Zum Beispiel habe ich die Werte 10-11-2009, 10/11/2009, 2009-11-10T07:00:00+0000die alle als Datumswerte erkannt werden sollen, und die Werte 200, 10, 350, die nicht als Datumswert erkannt werden. Was ist der einfachste Weg, dies zu überprüfen, wenn dies überhaupt möglich ist? Weil Zeitstempel auch erlaubt wären.

Thizzer
quelle

Antworten:

40

Würde Date.parse()ausreichen?

Siehe die entsprechende MDN-Dokumentationsseite .

Asmor
quelle
23
Seien Sie vorsichtig damit, da es immer noch eine Rückgabe für ungültige Daten im Februar zurückgibt, zum Beispiel: 2013-02-31
Leojh
58
Ein weiterer Grund zur Vorsicht: Zahlen werden als Datumsangaben analysiert. Date.parse("4.3")ist 986270400000.
Mogsdad
Ich habe versucht, mit den beiden oben genannten "Vorsicht" -Fällen herumzuspielen: console.log (Date.parse ("2013-02-31")); console.log (Date.parse ("4.3")); und in beiden Fällen (auf Firefox) gab es NaN zurück, daher scheint Date.parse für mich in Ordnung zu sein (ich bin ohnehin für Striche und die richtige Länge vor dem Parsen vorherrschend).
Cloudranger
55
Sorry @Asmor, das ist keine richtige Antwort. Date.parse analysiert jeden String mit einer Nummer, in der er sich befindet.
jwerre
11
Date.parse ("My Name 8") kommt als 99662040000, was falsch ist. Ich habe das benutzt und leide jetzt.
Rohith
250

Update 2015

Es ist eine alte Frage, aber andere neue Fragen wie:

Schließen Sie als Duplikate dieses, daher denke ich, dass es wichtig ist, hier einige neue Informationen hinzuzufügen. Ich schreibe es, weil ich Angst hatte, dass die Leute tatsächlich einen Teil des hier veröffentlichten Codes kopieren und einfügen und ihn in der Produktion verwenden.

Die meisten Antworten hier verwenden entweder einige komplexe reguläre Ausdrücke, die nur einigen sehr spezifischen Formaten entsprechen und diese tatsächlich falsch ausführen (z. B. den 32. Januar, wenn das tatsächliche ISO-Datum nicht wie angegeben übereinstimmt - siehe Demo ), oder sie versuchen, etwas an den DateKonstruktor und zu übergeben wünsche das Beste.

Moment nutzen

Wie ich in dieser Antwort erklärt habe, steht derzeit eine Bibliothek dafür zur Verfügung: Moment.js

Es ist eine Bibliothek zum Parsen, Validieren, Bearbeiten und Anzeigen von Datumsangaben in JavaScript. Sie verfügt über eine wesentlich umfangreichere API als die Standardfunktionen für die JavaScript-Datumsverarbeitung.

Es ist 12kB minimiert / gezippt und funktioniert in Node.js und anderen Orten:

bower install moment --save # bower
npm install moment --save   # npm
Install-Package Moment.js   # NuGet
spm install moment --save   # spm
meteor add momentjs:moment  # meteor

Mit Moment können Sie sehr genau festlegen, ob gültige Daten vorliegen. Manchmal ist es sehr wichtig, einige Hinweise zum erwarteten Format hinzuzufügen. Beispielsweise sieht ein Datum wie der 22.06.2015 wie ein gültiges Datum aus, es sei denn, Sie verwenden ein Format TT / MM / JJJJ. In diesem Fall sollte dieses Datum als ungültig abgelehnt werden. Es gibt nur wenige Möglichkeiten, wie Sie Moment mitteilen können, welches Format Sie erwarten, zum Beispiel:

moment("06/22/2015", "MM/DD/YYYY", true).isValid(); // true
moment("06/22/2015", "DD/MM/YYYY", true).isValid(); // false

Das trueArgument ist vorhanden, sodass der Moment nicht versucht, die Eingabe zu analysieren, wenn sie nicht genau einem der bereitgestellten Formate entspricht (es sollte meiner Meinung nach ein Standardverhalten sein).

Sie können ein intern bereitgestelltes Format verwenden:

moment("2015-06-22T13:17:21+0000", moment.ISO_8601, true).isValid(); // true

Und Sie können mehrere Formate als Array verwenden:

var formats = [
    moment.ISO_8601,
    "MM/DD/YYYY  :)  HH*mm*ss"
];
moment("2015-06-22T13:17:21+0000", formats, true).isValid(); // true
moment("06/22/2015  :)  13*17*21", formats, true).isValid(); // true
moment("06/22/2015  :(  13*17*21", formats, true).isValid(); // false

Siehe: DEMO .

Andere Bibliotheken

Wenn Sie Moment.js nicht verwenden möchten, gibt es auch andere Bibliotheken:

Update 2016

Ich habe das Immoment- Modul erstellt, das wie (eine Teilmenge von) Moment ist, aber keine Überraschungen aufweist, die durch die Mutation vorhandener Objekte verursacht werden ( weitere Informationen finden Sie in den Dokumenten ).

Update 2018

Heute empfehle ich die Verwendung von Luxon für die Datums- / Zeitmanipulation anstelle von Moment, wodurch (im Gegensatz zu Moment) alle Objekte unveränderlich werden, sodass es keine bösen Überraschungen im Zusammenhang mit der impliziten Mutation von Datumsangaben gibt.

Mehr Info

Siehe auch:

Eine Reihe von Artikeln von Rob Gravelle über JavaScript-Datumsanalysebibliotheken:

Endeffekt

Natürlich kann jeder versuchen, das Rad neu zu erfinden, einen regulären Ausdruck zu schreiben (aber bitte lesen Sie vorher ISO 8601 und RFC 3339, bevor Sie dies tun) oder Buit-In-Konstruktoren mit zufälligen Daten aufrufen, um Fehlermeldungen wie 'Invalid Date'(Sind Sie sicher, dass diese Nachricht ist) zu analysieren auf allen Plattformen genau gleich ? In allen Regionen? In der Zukunft?) oder Sie können eine getestete Lösung verwenden und Ihre Zeit nutzen, um sie zu verbessern, nicht neu zu erfinden. Alle hier aufgeführten Bibliotheken sind Open Source, freie Software.

rsp
quelle
4
wie genau sollte man das benutzen? moment("whatever 123").isValid()kehrt zurück true.
krivar
4
@krivar Es ist am besten, es so zu verwenden: moment("06/22/2015", "DD/MM/YYYY", true).isValid();mit dem explizit angegebenen erwarteten Datumsformat und einem Argument, truedas eine strikte Überprüfung bedeutet. Ich habe meine Antwort mit mehr Informationen und besseren Beispielen aktualisiert.
rsp
2
Das gleiche gilt, aber ich überprüfe Benutzereingaben und kenne das erwartete Datumsformat nicht ...
Jan Van der Haegen
3
@JanVanderHaegen Wenn davon ausgegangen werden kann, dass 3/4/5 ein gültiges Datum ist, ebenso wie der 1. April 2015, würde ich empfehlen, diese Formate (und möglicherweise noch viel mehr) zu einer expliziten Liste unterstützter Formate hinzuzufügen. Beachten Sie, dass der von Ihnen erwähnte 3/4/5 ohne explizites Format nicht eindeutig ist.
rsp
3
Dies könnte die beste und am besten gepflegte Antwort sein, die ich auf SO
Phil3992
62

So habe ich dieses Problem in einer App gelöst, an der ich gerade arbeite:

aktualisiert basierend auf dem Feedback von krillgar:

var isDate = function(date) {
    return (new Date(date) !== "Invalid Date") && !isNaN(new Date(date));
}
Neil Girardi
quelle
5
Ich musste zurückkehren (neues Datum (Datum)). ToString ()! == "Ungültiges Datum" für den Knoten. Beachten Sie auch, dass? true: false ist redundant. Hier reicht es aus, nur den Ausdruck zurückzugeben.
Domenukk
Gibt in IE8 new Date(date)kein "Ungültiges Datum" an.
Krillgar
13
Dies ist keine gute Antwort. new Date(date) !== "Invalid Date"wird immer zurückkehren wahr der linke Ausdruck mit einem ZeitWert ein Date - Objekt wird zurückkehren , da NaN , das nie sein kann , ===in einen String. Verwendung von =="funktioniert" aufgrund der Typkonvertierung. Da das Parsen von Datumszeichenfolgen jedoch immer noch weitgehend von der Implementierung abhängt, ist es für uns schwerwiegend fehlerhaft, zufällige Formate zu analysieren.
RobG
4
neues Datum ("469") ergibt Di 01. Januar 469 00:00:00 GMT + 0200 (EET)
Dan Ochiana
3
Dies ähnelt der falsch akzeptierten richtigen Antwort. isDate('Mac OS X 10.14.2')gibt hier true zurück.
BradStell
24

new Date(date) === 'Invalid Date'funktioniert nur in Firefox und Chrome. IE8 (der, den ich zu Testzwecken auf meinem Computer habe) gibt NaN.

Wie in der akzeptierten Antwort angegeben, Date.parse(date)funktioniert dies auch für Zahlen. Um dies zu umgehen, können Sie auch überprüfen, ob es sich nicht um eine Zahl handelt (wenn Sie dies bestätigen möchten).

var parsedDate = Date.parse(date);

// You want to check again for !isNaN(parsedDate) here because Dates can be converted
// to numbers, but a failed Date parse will not.
if (isNaN(date) && !isNaN(parsedDate)) {
    /* do your work */
}
Krillgar
quelle
2
Mir ist klar, dass es ein paar Jahre später ist, aber es isNanist keine Funktion; falscher Fall in der ersten Instanz.
Tim Lewis
Funktioniert nicht. Wenn dateja Foostreet 1, wird Ihr Zustand als wahr bewertet.
Fabian Picone
9

Wie wäre es mit so etwas? Es wird getestet, ob es sich um ein Datumsobjekt oder eine Datumszeichenfolge handelt:

function isDate(value) {
    var dateFormat;
    if (toString.call(value) === '[object Date]') {
        return true;
    }
    if (typeof value.replace === 'function') {
        value.replace(/^\s+|\s+$/gm, '');
    }
    dateFormat = /(^\d{1,4}[\.|\\/|-]\d{1,2}[\.|\\/|-]\d{1,4})(\s*(?:0?[1-9]:[0-5]|1(?=[012])\d:[0-5])\d\s*[ap]m)?$/;
    return dateFormat.test(value);
}

Ich sollte erwähnen, dass dies nicht auf ISO-formatierte Zeichenfolgen getestet wird, aber mit etwas mehr Arbeit an RegExp sollten Sie gut sein.

jwerre
quelle
7

Keine der Antworten hier befasst sich mit der Überprüfung, ob das Datum ungültig ist, wie z. B. dem 31. Februar. Diese Funktion behebt dies, indem sie überprüft, ob der zurückgegebene Monat dem ursprünglichen Monat entspricht, und sicherstellt, dass ein gültiges Jahr angegeben wurde.

//expected input dd/mm/yyyy or dd.mm.yyyy or dd-mm-yyyy
function isValidDate(s) {
  var separators = ['\\.', '\\-', '\\/'];
  var bits = s.split(new RegExp(separators.join('|'), 'g'));
  var d = new Date(bits[2], bits[1] - 1, bits[0]);
  return d.getFullYear() == bits[2] && d.getMonth() + 1 == bits[1];
} 
ykay sagt Reinstate Monica
quelle
Denn die Frage ist nicht, ob überprüft werden soll, ob eine Zeichenfolge ein 'gültiges' Datum ist, sondern nur, ob eine Zeichenfolge ein Datumsformat darstellt.
Thizzer
@ Thizzer guter Punkt. Es würde mir nichts ausmachen, das Problem zu beheben, aber beim erneuten Lesen Ihrer Frage bin ich ratlos, weil Sie sagen, 10 sollte nicht validiert werden, aber Zeitstempel sollten zulässig sein.
Ykay sagt Reinstate Monica
xD hat das nicht einmal bemerkt, eine Frage aus meinen früheren Tagen mit Datums- / Zeitstempeln. Ich werde versuchen, die Frage später heute zu bearbeiten.
Thizzer
Warum Monat 1 und dann Monat + 1?
Kapil Raghuwanshi
@KapilRaghuwanshi Javascript-Daten verwenden einen auf Null basierenden Monat, daher müssen Sie 1 subtrahieren, um das richtige Datum zu erstellen, und 1 hinzufügen, um zu überprüfen, ob es dem ursprünglichen Monat entspricht
ykay sagt Reinstate Monica
5

Verwenden Sie den regulären Ausdruck, um ihn zu validieren.

isDate('2018-08-01T18:30:00.000Z');

isDate(_date){
        const _regExp  = new RegExp('^(-?(?:[1-9][0-9]*)?[0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])(.[0-9]+)?(Z)?$');
        return _regExp.test(_date);
    }
lpradhap
quelle
4

Durch Bezugnahme auf alle obigen Kommentare bin ich zu einer Lösung gekommen.

Dies funktioniert, wenn das Dateübergebene Format im ISO-Format vorliegt oder für andere Formate bearbeitet werden muss.

var isISO = "2018-08-01T18:30:00.000Z";

if (new Date(isISO) !== "Invalid Date" && !isNaN(new Date(isISO))) {
    if(isISO == new Date(isISO).toISOString()) {
        console.log("Valid date");
    } else {
        console.log("Invalid date");
    }
} else {
    console.log("Invalid date");
}

Sie können hier auf JSFiddle spielen.

Nikhil Zurunge
quelle
1
Diese Lösung hat für mich am besten funktioniert, da die von meiner App unterstützten Datumszeichenfolgen das Format haben. Daher ist YYYY-MM-DDes trivial, T00:00:00.000Zdiese Lösung anzuhängen und zu verwenden, um nach gültigen Zeichenfolgen zu suchen.
Beschleunigen Sie den
Für Javascript funktioniert dies, aber wie wird es in Typoskript verwendet?
Sae
3

Hier ist eine verbesserte Funktion, die nur verwendet Date.parse():

function isDate(s) {
    if(isNaN(s) && !isNaN(Date.parse(s)))
        return true;
    else return false;
}

Hinweis: Date.parse () analysiert Zahlen : Gibt beispielsweise Date.parse(1)ein Datum zurück. Hier prüfen wir also, ob ses sich nicht um eine Nummer handelt, ob es sich um ein Datum handelt.

A-Sharabiani
quelle
1
Dies funktioniert nicht, da das Bestehen von 'Test 2' als wahres Datum gilt. getestet in der neuesten Version von Chrome
user1751287
2

Ich würde das tun

var myDateStr= new Date("2015/5/2");

if( ! isNaN ( myDateStr.getMonth() )) {
    console.log("Valid date");
}
else {
    console.log("Invalid date");
}

Spielen Sie hier

kiranvj
quelle
2
Dies funktioniert in aktuellem Chrome nicht, möglicherweise auch in anderen Browsern. Ich habe die angegebene Zeichenfolge in geändert EXAMPLE STRING 12345und sie gibt "Gültiges Datum" zurück.
1

Hier ist eine minimalistische Version.

var isDate = function (date) {
    return!!(function(d){return(d!=='Invalid Date'&&!isNaN(d))})(new Date(date));
}
Mr. Polywhirl
quelle
1
Funktioniert immer noch nicht für mein Beispiel:isDate("  1")
Tomas
@ Tom Sie sollten überprüfen, ob der Wert Leerzeichen enthält, bevor Sie feststellen, ob es sich um ein Datum handelt. Ihr Problem ist ein Sonderfall, der von Ihrer Steuerungslogik behandelt werden muss.
Mr. Polywhirl
1
Das Überprüfen auf Leerzeichen sollte nicht erforderlich sein, da die Zeichenfolge 1. Januar 2020 ein gültiges Datum ist, das Leerzeichen enthält. Ihre Methode berücksichtigt dies nicht.
Kirstin Walsh
1

Diese aufrufbare Funktion funktioniert einwandfrei und gibt für das gültige Datum true zurück. Rufen Sie unbedingt mit einem Datum im ISO-Format an (JJJJ-MM-TT oder JJJJ / MM / TT):

function validateDate(isoDate) {

    if (isNaN(Date.parse(isoDate))) {
        return false;
    } else {
        if (isoDate != (new Date(isoDate)).toISOString().substr(0,10)) {
            return false;
        }
    }
    return true;
}
Peter DK
quelle
1
Es ist gut, aber es beantwortet die Frage nicht vollständig. Insbesondere funktioniert es nicht für '2009-11-10T07: 00: 00 + 0000', eines der angegebenen Beispiele.
Amadan
Denken Sie nicht, dass dies so funktioniert, wie es sollte validateDate ('2016-12-30T08: 00: 00.000Z') // false
Jose Browne
Unabhängig davon, ob dies funktioniert oder nicht, könnte es vereinfacht werden alsreturn !isNaN(Date.parse(isoDate)) || isoDate == new Date(isoDate).toISOString().substr(0,10);
Michel Jung
1

Ich weiß, dass es eine alte Frage ist, aber ich hatte das gleiche Problem und sah, dass keine der Antworten richtig funktionierte - insbesondere das Aussortieren von Zahlen (1.200.345 usw.) aus Daten, was die ursprüngliche Frage ist. Hier ist eine ziemlich unorthodoxe Methode, die mir einfällt und die zu funktionieren scheint. Bitte weisen Sie darauf hin, wenn es Fälle gibt, in denen dies fehlschlägt.

if(sDate.toString() == parseInt(sDate).toString()) return false;

Dies ist die Zeile, um Zahlen auszusortieren. Somit könnte die gesamte Funktion folgendermaßen aussehen:

function isDate(sDate) {  
  if(sDate.toString() == parseInt(sDate).toString()) return false; 
  var tryDate = new Date(sDate);
  return (tryDate && tryDate.toString() != "NaN" && tryDate != "Invalid Date");  
}

console.log("100", isDate(100));
console.log("234", isDate("234"));
console.log("hello", isDate("hello"));
console.log("25 Feb 2018", isDate("25 Feb 2018"));
console.log("2009-11-10T07:00:00+0000", isDate("2009-11-10T07:00:00+0000"));

Peekolo
quelle
1
console.log("hello 1 ", isDate("hello 1 "));gibt wahr zurück
John
Sie haben Recht! Hast du eine Lösung? Bis jetzt denke ich, dass keine der Antworten hier die Frage wirklich angemessen angesprochen hat!
Peekolo
"100%", ein Prozentsatz, gibt true zurück
toddmo
0

Ist es in Ordnung zu prüfen, ob für das Objekt eine datumsbezogene Funktion verfügbar ist, um festzustellen, ob es sich um ein Datumsobjekt handelt oder nicht?

mögen

var l = new Date();
var isDate = (l.getDate !== undefined) ? true; false;
Kishore Relangi
quelle
0

So mache ich es am Ende. Dies wird nicht alle Formate abdecken. Sie müssen entsprechend anpassen. Ich habe die Kontrolle über das Format, also funktioniert es für mich

function isValidDate(s) {
            var dt = "";
            var bits = [];
            if (s && s.length >= 6) {
                if (s.indexOf("/") > -1) {
                    bits = s.split("/");
                }
                else if (s.indexOf("-") > -1) {
                    bits = s.split("-");
                }
                else if (s.indexOf(".") > -1) {
                    bits = s.split(".");
                }
                try {
                    dt = new Date(bits[2], bits[0] - 1, bits[1]);
                } catch (e) {
                    return false;
                }
                return (dt.getMonth() + 1) === parseInt(bits[0]);
            } else {
                return false;
            }
        }
kheya
quelle
-1

Ok, das ist eine alte Frage, aber ich habe eine andere Lösung gefunden, als ich die Lösungen hier überprüft habe. Bei mir wird geprüft, ob die Funktion getTime () am Datumsobjekt vorhanden ist:

const checkDate = new Date(dateString);

if (typeof checkDate.getTime !== 'function') {
  return;
}
m.steini
quelle
-1

document.getElementById('r1').innerHTML = dayjs('sdsdsd').isValid()

document.getElementById('r2').innerHTML = dayjs('2/6/20').isValid()
<script src="https://unpkg.com/[email protected]/dayjs.min.js"></script>

<p>'sdsdsd' is a date: <span id="r1"></span></p>
<p>'2/6/20' is a date: <span id="r2"></span></p>

Eine leichte Bibliothek steht für Sie bereit: Day.js

Kein Schlüssel
quelle
Dies ist im Grunde Werbung auf StackOverflow, tun Sie das nicht.
c4sh
-4
SimpleDateFormat sdf = new SimpleDateFormat(dateFromat);
sdf.setLenient(false);

Standardmäßig ist dies auf TRUE gesetzt. Selbst Zeichenfolgen mit falschem Format geben also gute Werte zurück.

Ich habe es so etwas benutzt:

SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd");
formatter.setLenient(false);
String value = "1990/13/23"; 

try {
      Date date = formatter.parse(value);
      System.out.println(date);
    }catch (ParseException e) 
  {
    System.out.println("its bad");
  }
Anupam Mahapatra
quelle
5
... Javascript?!
Artparks
-5

Versuche dies:

if (var date = new Date(yourDateString)) {
    // if you get here then you have a valid date       
}
Andrew Hare
quelle
6
Das funktioniert bei mir nicht. Zuerst wird die Variable in der Bedingung nicht analysiert, aber wenn Sie das entfernen und so etwas versuchen: if (Datum = neues Datum ("Müll")) {alert (Datum); } Selbst wenn das Datum Müll ist, wird die Warnung weiterhin ausgeführt, da die Datumsfunktion "Ungültiges Datum" zurückgibt (zumindest unter Firefox), sodass die Bedingung als wahr ausgewertet wird. Ich denke, wenn einige Browser am ungültigen Datum null zurückgeben, würde es auf diesen Browsern funktionieren. Hier kann es zu Browser-Inkonsistenzen kommen.
Cloudranger