Schnellste Möglichkeit, um festzustellen, ob eine Zeichenfolge ein gültiges Datum ist
Unterstütze ich eine gemeinsame Bibliothek bei der Arbeit, dass führt viele Kontrollen aus einer angegebenen Zeichenfolge, um zu sehen, ob es ein gültiges Datum ist. Die Java-API, commons-lang-library, und JodaTime haben alle Methoden, die Parsen einen string und ein Datum, damit Sie wissen, ob es sich tatsächlich um ein gültiges Datum ist oder nicht, aber ich hatte gehofft, dass es wäre eine Art zu tun, der Validierung, ohne tatsächlich die Schaffung eines date-Objekt (oder DateTime-wie ist der Fall mit der JodaTime-Bibliothek). Zum Beispiel hier ist ein einfaches Stück Beispiel-code:
public boolean isValidDate(String dateString) {
SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd");
try {
df.parse(dateString);
return true;
} catch (ParseException e) {
return false;
}
}
Scheint es einfach verschwenderisch zu mir, wir werden wegwerfen die resultierende Objekt. Aus meinen benchmarks etwa 5% unserer Zeit in diesem gemeinsamen Bibliothek verbracht Validierung der Daten. Ich hoffe, ich bin nur fehlt eine offensichtliche API. Irgendwelche Vorschläge wäre toll!
UPDATE
Davon ausgehen, dass wir immer das gleiche Datumsformat zu allen Zeiten (wahrscheinlich JJJJMMTT). Ich dachte über die Verwendung von regex, aber dann würde es brauchen, um sich bewusst von der Anzahl der Tage in jedem Monat, Schaltjahre, usw...
Ergebnisse
Analysiert eine Datum 10 Millionen mal
Using Java's SimpleDateFormat: ~32 seconds
Using commons-lang DateUtils.parseDate: ~32 seconds
Using JodaTime's DateTimeFormatter: ~3.5 seconds
Using the pure code/math solution by Slanec: ~0.8 seconds
Using precomputed results by Slanec and dfb (minus filling cache): ~0.2 seconds
Gab es einige sehr kreative Antworten, ich weiß es zu schätzen! Ich denke, jetzt brauche ich nur zu entscheiden, wie viel Flexibilität, die ich brauche, was ich will, der code Aussehen soll. Ich werde sagen, dass der dfb die Antwort ist richtig, denn es war rein der Schnellste, das war meine ursprüngliche Frage. Danke!
InformationsquelleAutor der Frage jjathman | 2012-07-14
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wenn Sie wirklich besorgt über die Leistung und Ihre Datum-format ist wirklich so einfach, genau vorherberechnet werden alle gültigen strings und hash in den Speicher. Das format, das Sie haben oben nur ~ 8 Millionen gültige Kombinationen bis 2050
BEARBEITEN von Slanec - Referenz-Implementierung
Dieser Umsetzung hängt von Ihren spezifischen dateformat. Es könnten angepasst werden, um jede spezifische dateformat gibt (genau wie meine erste Antwort, aber ein bisschen besser).
Macht es eine Menge aller
dates
von 1900 bis 2050 (als Zeichenfolgen gespeichert werden - es gibt 54787) und vergleicht dann den angegebenen Terminen mit diesen gespeichert.Einmal die
dates
aufgebaut wird, es ist schnell wie die Hölle. Eine schnelle microbenchmark zeigte eine Verbesserung um einen Faktor 10 gegenüber meiner ersten Lösung.P. S. Es kann geändert werden, um
Set<Integer>
oder sogar Fundgrube'sTIntHashSet
das reduziert den Speicherverbrauch viel (und daher ermöglicht die Verwendung einer viel größeren Zeitspanne), die Leistung fällt dann auf ein Niveau knapp unterhalb meine ursprüngliche Lösung.InformationsquelleAutor der Antwort dfb
Sie zurückgreifen können, Ihr denken - versuchen zu scheitern, so schnell wie möglich, wenn die Zeichenfolge definitiv ist kein Datum:
null
length
ist nicht 8 (basierend auf deinem Beispiel Datum-format!)Wenn keiner von denen zutreffen, dann versuchen Sie zu analysieren - vorzugsweise mit einer vorgefertigten statischen
Format
Objekt, nicht auf jede Methode, die ausgeführt wird.BEARBEITEN nach Kommentaren
Basierend auf dieser nette trick, schrieb ich eine schnelle Validierung der Methode. Es sieht häßlich aus, aber ist deutlich schneller als die üblichen Bibliothek Methoden (die sollten in jeder standard-situation!), da es stützt sich auf Ihre bestimmten Datum format und keine
Date
Objekt. Es behandelt das Datum alsint
und geht aus.Getestet habe ich die
daysInMonth()
Methode, die nur ein bisschen (das Schaltjahr Zustand von Peter Lawrey), so dass ich hoffe, dass es keine offensichtlichen Fehler.Einen schnellen (geschätzt!) microbenchmark ergab sich eine Beschleunigung um einen Faktor von 30.
P. S. Dein Beispiel oben genannte Methode zurück
true
für "99999999". Mir wird nur true zurückgegeben, für vorhandene Daten :).InformationsquelleAutor der Antwort Petr Janeček
Ich denke, dass der bessere Weg zu wissen, ob zu einem bestimmten Datum gültig ist, ist die Definition einer Methode wie:
Einerseits die Methode überprüft das Datum mit dem richtigen format , und auf der anderen Seite prüft das Datum entspricht ein gültiges Datum ist . Zum Beispiel das Datum "2015/02/29" analysiert werden, um "2015/03/01", so die input-und output anders sein wird, und die Methode false zurückgeben.
InformationsquelleAutor der Antwort victor.hernandez
Aufbauend auf die Antwort von dfb-konnten Sie eine zwei-Schritt-hash.
InformationsquelleAutor der Antwort Arcymag
Könnte man eine Kombination von-regex-und-Handbuch-ein Schaltjahr-überprüfung. Also:
InformationsquelleAutor der Antwort Ingo
wenn es gibt i = 2 bedeutet, dass das Datum ungültig ist und gibt 1 zurück, wenn das Datum gültig ist
InformationsquelleAutor der Antwort Sudeep Singh
LocalDate.parse(uncheckedStringDate, DateTimeFormatter.BASIC_ISO_DATE)
InformationsquelleAutor der Antwort Rakesh