So überprüfen Sie ein Datum in Java [geschlossen]


81

Ich finde es merkwürdig, dass die naheliegendste Art, DateObjekte in Java zu erstellen , veraltet ist und anscheinend durch einen nicht so offensichtlichen, nachsichtigen Kalender ersetzt wurde.

Wie überprüfen Sie, ob ein Datum, das als Kombination aus Tag, Monat und Jahr angegeben wird, ein gültiges Datum ist?

Zum Beispiel wäre der 31.02.2008 (wie in JJJJ-MM-TT) ein ungültiges Datum.


Überlegen Sie bei Fragen mit ähnlichen Fragen, ob Sie nicht-gregorianische Kalenderunterstützung benötigen.
MSalters

@JasonC Ich stimme Ihnen voll und ganz zu. Das Zusammenführen scheint der beste Weg zu sein.
acm

Antworten:


37

Derzeit wird die Kalenderklasse verwendet. Es verfügt über die setLenient- Methode, die das Datum und den Auslöser sowie die Ausnahme überprüft , wenn sie außerhalb des Bereichs liegt, wie in Ihrem Beispiel.

Das Hinzufügen wurde vergessen: Wenn Sie eine Kalenderinstanz erhalten und die Uhrzeit anhand Ihres Datums festlegen, erhalten Sie auf diese Weise die Validierung.

Calendar cal = Calendar.getInstance();
cal.setLenient(false);
cal.setTime(yourDate);
try {
    cal.getTime();
}
catch (Exception e) {
  System.out.println("Invalid date");
}

2
Ich glaube nicht, dass dies genau so funktioniert, wie es ist. Calendar.setTime benötigt java.util.Date, sodass die Konvertierung von Zeichenfolgen bereits erfolgt ist, wenn Sie ein "yourDate" -Objekt erhalten.
Verspätung

32
3 Probleme mit dem Beispielcode: 1. Nachdem Sie eine Kalenderinstanz erhalten haben, müssen Sie cal.setLenient (false) aufrufen. Andernfalls gilt ein Datum wie der 31. Februar 2007 als gültig. 2. Eine Ausnahme wird von cal.setTime () nicht ausgelöst. Sie müssen cal.getTime () nach dem Aufruf von setTime () aufrufen, wodurch bei ungültigem Datum eine Ausnahme ausgelöst wird. 3. Tippfehler: Es fehlt ein '}' vor dem Fang.
Liron Yahdav

Dies ist auch langsamer als bei anderen Ansätzen. Siehe stackoverflow.com/questions/2149680/…
Despot

4
Zu Ihrer Information, die störenden alten Datum Zeitklassen wie java.util.Date, java.util.Calendarund java.text.SimpleDateFormatsind jetzt Erbe , durch die verdrängte java.time Klassen in Java gebaut 8 und höher. Siehe Tutorial von Oracle .
Basil Bourque

3
validiert keine Daten wie den 31. Februar
Shikha Singh

76

Schlüssel ist df.setLenient (false); . Dies ist mehr als genug für einfache Fälle. Wenn Sie nach einer robusteren (ich bezweifle) und / oder alternativen Bibliothek wie joda-time suchen, dann schauen Sie sich die Antwort des Benutzers "tardate" an.

final static String DATE_FORMAT = "dd-MM-yyyy";

public static boolean isDateValid(String date) 
{
        try {
            DateFormat df = new SimpleDateFormat(DATE_FORMAT);
            df.setLenient(false);
            df.parse(date);
            return true;
        } catch (ParseException e) {
            return false;
        }
}

1
Versuchen Sie es mit "09-04-201a". Es wird ein verrücktes Date schaffen.
ceklock

@ceklock So funktioniert es, egal ob Sie verwenden setLenientoder nicht: SimpleDateFormatWird immer analysiert, bis das Muster übereinstimmt, und den Rest der Zeichenfolge ignorieren, sodass Sie 201als Jahr erhalten.
Daniel Naber

@ceklock Ich habe es gerade in meiner Lösung angesprochen . Es kann ein oder zwei Minuten für jemanden sparen.
Sufian

1
Das Einbeziehen der Ausnahmebehandlung führt zu einem großen Leistungseinbruch. Dies ist daher wahrscheinlich ein schlechtes Design, wenn Sie im normalen Betrieb fehlerhafte Eingaben erwarten (z. B. Überprüfen von Benutzereingaben). Wenn die Methode jedoch als Doppelprüfung gegen Eingaben verwendet wird, die ständig gültig sein sollen (mit Ausnahme von Fehlern), ist dies in Ordnung.
Aaron

2
Zu Ihrer Information, die furchtbar lästig alten Datum Zeitklassen wie java.util.Date, java.util.Calendarund java.text.SimpleDateFormatsind jetzt Erbe , durch die verdrängte java.time Klassen in Java gebaut 8 und höher. Siehe Tutorial von Oracle .
Basil Bourque

48

Wie von @Maglob gezeigt, besteht der grundlegende Ansatz darin, die Konvertierung von Zeichenfolge zu Datum mithilfe von SimpleDateFormat.parse zu testen . Dadurch werden ungültige Tag / Monat-Kombinationen wie der 31.02.2008 abgefangen.

In der Praxis ist dies jedoch selten genug, da SimpleDateFormat.parse äußerst liberal ist. Es gibt zwei Verhaltensweisen, mit denen Sie sich befassen könnten:

Ungültige Zeichen in der Datumszeichenfolge Überraschenderweise wird 2008-02-2x als gültiges Datum mit dem Gebietsschema format = "JJJJ-MM-TT" übergeben. Auch wenn isLenient == false ist.

Jahre: 2, 3 oder 4 Ziffern? Möglicherweise möchten Sie auch 4-stellige Jahre erzwingen, anstatt das Standardverhalten von SimpleDateFormat zuzulassen (das "12-02-31" unterschiedlich interpretiert, je nachdem, ob Ihr Format "JJJJ-MM-TT" oder "JJJ-MM-TT" war. )

Eine strikte Lösung mit der Standardbibliothek

Ein vollständiger String-to-Date-Test könnte also so aussehen: eine Kombination aus Regex-Match und einer erzwungenen Datumskonvertierung. Der Trick mit dem regulären Ausdruck besteht darin, ihn länderspezifisch zu gestalten.

  Date parseDate(String maybeDate, String format, boolean lenient) {
    Date date = null;

    // test date string matches format structure using regex
    // - weed out illegal characters and enforce 4-digit year
    // - create the regex based on the local format string
    String reFormat = Pattern.compile("d+|M+").matcher(Matcher.quoteReplacement(format)).replaceAll("\\\\d{1,2}");
    reFormat = Pattern.compile("y+").matcher(reFormat).replaceAll("\\\\d{4}");
    if ( Pattern.compile(reFormat).matcher(maybeDate).matches() ) {

      // date string matches format structure, 
      // - now test it can be converted to a valid date
      SimpleDateFormat sdf = (SimpleDateFormat)DateFormat.getDateInstance();
      sdf.applyPattern(format);
      sdf.setLenient(lenient);
      try { date = sdf.parse(maybeDate); } catch (ParseException e) { }
    } 
    return date;
  } 

  // used like this:
  Date date = parseDate( "21/5/2009", "d/M/yyyy", false);

Beachten Sie, dass der reguläre Ausdruck davon ausgeht, dass die Formatzeichenfolge nur Tag-, Monats-, Jahres- und Trennzeichen enthält. Abgesehen davon kann das Format in einem beliebigen Gebietsschemaformat vorliegen: "TT / MM / JJ", "JJJJ-MM-TT" usw. Die Formatzeichenfolge für das aktuelle Gebietsschema kann folgendermaßen abgerufen werden:

Locale locale = Locale.getDefault();
SimpleDateFormat sdf = (SimpleDateFormat)DateFormat.getDateInstance(DateFormat.SHORT, locale );
String format = sdf.toPattern();

Joda Time - Bessere Alternative?

Ich habe kürzlich von joda time gehört und dachte, ich würde vergleichen. Zwei Punkte:

  1. Scheint im Gegensatz zu SimpleDateFormat besser darin zu sein, ungültige Zeichen in der Datumszeichenfolge streng zu betrachten
  2. Ich kann noch keine Möglichkeit finden, 4-stellige Jahre damit durchzusetzen (aber ich denke, Sie könnten zu diesem Zweck Ihren eigenen DateTimeFormatter erstellen ).

Es ist ganz einfach zu bedienen:

import org.joda.time.format.*;
import org.joda.time.DateTime;

org.joda.time.DateTime parseDate(String maybeDate, String format) {
  org.joda.time.DateTime date = null;
  try {
    DateTimeFormatter fmt = DateTimeFormat.forPattern(format);
    date =  fmt.parseDateTime(maybeDate);
  } catch (Exception e) { }
  return date;
}

Am Ende hatte ich die Joda-Alternative und überprüfte selbst, ob der Wert mit der Musterlänge übereinstimmt ...
Xtreme Biker

Update: Die schrecklichen alten Legacy - Klassen ( Date, SimpleDateFormatusw.) wird jetzt von den modernen verdrängten java.time Klassen. Ebenso befindet sich das Joda-Time- Projekt im Wartungsmodus und empfiehlt die Migration zu den Klassen java.time .
Basil Bourque

38

Sie können SimpleDateFormat verwenden

Zum Beispiel so etwas wie:

boolean isLegalDate(String s) {
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    sdf.setLenient(false);
    return sdf.parse(s, new ParsePosition(0)) != null;
}

2
Eines der Probleme bei diesem Ansatz ist, dass er 0003-0002-001 akzeptiert.
Despot

1
Ein weiteres Problem ist, dass die Einstellung 13 im Monat ein Datum zurückgibt, an dem der Monat 01 im folgenden Jahr ist.
8bitjunkie

Zu Ihrer Information, die furchtbar lästig alten Datum Zeitklassen wie java.util.Date, java.util.Calendarund java.text.SimpleDateFormatsind jetzt Erbe , durch die verdrängte java.time Klassen in Java gebaut 8 und höher. Siehe Tutorial von Oracle .
Basil Bourque

24

tl; dr

Verwenden Sie den strengen Modus, um a java.time.DateTimeFormatterzu analysieren LocalDate. Falle für die DateTimeParseException.

LocalDate.parse(                   // Represent a date-only value, without time-of-day and without time zone.
    "31/02/2000" ,                 // Input string.
    DateTimeFormatter              // Define a formatting pattern to match your input string.
    .ofPattern ( "dd/MM/uuuu" )
    .withResolverStyle ( ResolverStyle.STRICT )  // Specify leniency in tolerating questionable inputs.
)

Nach dem Parsen können Sie nach einem angemessenen Wert suchen. Zum Beispiel ein Geburtsdatum innerhalb der letzten hundert Jahre.

birthDate.isAfter( LocalDate.now().minusYears( 100 ) )

Vermeiden Sie ältere Datums- und Zeitklassen

Vermeiden Sie die Verwendung der problematischen alten Datums- / Uhrzeitklassen, die mit den frühesten Java-Versionen geliefert werden. Jetzt ersetzt durch die java.time- Klassen.

LocalDate& DateTimeFormatter&ResolverStyle

Die LocalDateKlasse repräsentiert einen Nur-Datum-Wert ohne Tageszeit und ohne Zeitzone.

String input = "31/02/2000";
DateTimeFormatter f = DateTimeFormatter.ofPattern ( "dd/MM/uuuu" );
try {
    LocalDate ld = LocalDate.parse ( input , f );
    System.out.println ( "ld: " + ld );
} catch ( DateTimeParseException e ) {
    System.out.println ( "ERROR: " + e );
}

Die java.time.DateTimeFormatterKlasse kann so eingestellt werden, dass Zeichenfolgen mit einem der drei in der ResolverStyleAufzählung definierten Kronzeugenmodi analysiert werden . Wir fügen eine Zeile in den obigen Code ein, um jeden der Modi auszuprobieren.

f = f.withResolverStyle ( ResolverStyle.LENIENT );

Die Ergebnisse:

  • ResolverStyle.LENIENT
    ld: 2000-03-02
  • ResolverStyle.SMART
    ld: 2000-02-29
  • ResolverStyle.STRICT
    FEHLER: java.time.format.DateTimeParseException: Text '31 / 02/2000 'konnte nicht analysiert werden: Ungültiges Datum' 31. FEBRUAR '

Wir können sehen, dass im ResolverStyle.LENIENTModus das ungültige Datum um eine entsprechende Anzahl von Tagen verschoben wird. Im ResolverStyle.SMARTModus (Standardeinstellung) wird eine logische Entscheidung getroffen, das Datum innerhalb des Monats zu halten und mit dem letztmöglichen Tag des Monats, dem 29. Februar, in einem Schaltjahr fortzufahren, da es in diesem Monat keinen 31. Tag gibt. Der ResolverStyle.STRICTModus löst eine Ausnahme aus, die sich darüber beschwert, dass es kein solches Datum gibt.

Alle drei sind je nach Geschäftsproblem und Richtlinien angemessen. Klingt so, als ob Sie in Ihrem Fall möchten, dass der strikte Modus das ungültige Datum ablehnt, anstatt es anzupassen.


Tabelle aller Datums- und Uhrzeittypen in Java, sowohl moderne als auch ältere.


Über java.time

Der java.time Rahmen in Java 8 gebaut und später. Diese Klassen verdrängen die lästigen alten Legacy - Datum-Zeit - Klassen wie java.util.Date, Calendar, & SimpleDateFormat.

Weitere Informationen finden Sie im Oracle-Lernprogramm . Suchen Sie im Stapelüberlauf nach vielen Beispielen und Erklärungen. Die Spezifikation ist JSR 310 .

Das Joda-Time- Projekt, das sich jetzt im Wartungsmodus befindet , empfiehlt die Migration zu den Klassen java.time .

Sie können java.time- Objekte direkt mit Ihrer Datenbank austauschen . Verwenden Sie einen JDBC-Treiber, der mit JDBC 4.2 oder höher kompatibel ist . Keine Notwendigkeit für Strings, keine Notwendigkeit für java.sql.*Klassen.

Woher bekomme ich die java.time-Klassen?

Tabelle, welche java.time-Bibliothek mit welcher Java- oder Android-Version verwendet werden soll

Das ThreeTen-Extra- Projekt erweitert java.time um zusätzliche Klassen. Dieses Projekt ist ein Testfeld für mögliche zukünftige Ergänzungen von java.time. Sie können einige nützliche Klassen hier wie finden Interval, YearWeek, YearQuarter, und mehr .


Angenommen, das Projekt wird mit Java 8+ kompiliert, dann ist Ihre Antwort richtig. Ich benutze diese Klassen auch, wenn sich das Projekt in Java 8 befindet. Aber manchmal muss ich diese hässlichen alten JSP-Scriptlets berühren (die Java 7 sogar nicht unterstützen). Bei der Validierung von Daten gibt es Schmerzen. Daher bin ich hier. Ihre Antwort ist jedoch der richtigste Ansatz ... Fazit: Ich bin beschissen.
KarelG

@KarelG Lesen Sie den vorletzten Absatz über den Backport nach Java 6 und Java 7 erneut . Ich habe dieses Verhalten im Backport nicht überprüft, aber ich schlage vor, Sie probieren es aus.
Basil Bourque

14

java.time

Mit der in Java 8 und höher integrierten Datums- und Zeit-API ( java.time- Klassen) können Sie die LocalDateKlasse verwenden.

public static boolean isDateValid(int year, int month, int day) {
    boolean dateIsValid = true;
    try {
        LocalDate.of(year, month, day);
    } catch (DateTimeException e) {
        dateIsValid = false;
    }
    return dateIsValid;
}

2
Standardmäßig wird in diesem Code ResolverStyle.SMARTder resultierende Wert an ein gültiges Datum angepasst, anstatt eine Ausnahme auszulösen. Dieser Code wird also das Ziel der Frage nicht erreichen. Siehe meine Antwort zum Beispiel und zur Lösung mit ResolverStyle.STRICT.
Basil Bourque

7

Eine alternative strikte Lösung unter Verwendung der Standardbibliothek besteht darin, Folgendes auszuführen:

1) Erstellen Sie ein striktes SimpleDateFormat mit Ihrem Muster

2) Versuchen Sie, den vom Benutzer eingegebenen Wert mithilfe des Formatierungsobjekts zu analysieren

3) Wenn erfolgreich, formatieren Sie das aus (2) resultierende Datum mit demselben Datumsformat neu (aus (1)).

4) Vergleichen Sie das neu formatierte Datum mit dem ursprünglichen, vom Benutzer eingegebenen Wert. Wenn sie gleich sind, stimmt der eingegebene Wert genau mit Ihrem Muster überein.

Auf diese Weise müssen Sie keine komplexen regulären Ausdrücke erstellen. In meinem Fall musste ich die gesamte Mustersyntax von SimpleDateFormat unterstützen, anstatt mich auf bestimmte Typen wie Tage, Monate und Jahre zu beschränken.


Dies ist definitiv der richtige
Victor Ionescu

7

Aufbauend auf Aravinds Antwort zur Behebung des Problems, auf das ceklock in seinem Kommentar hingewiesen hat , habe ich eine Methode hinzugefügt, um zu überprüfen, ob das dateStringZeichen kein ungültiges Zeichen enthält.

So mache ich das:

private boolean isDateCorrect(String dateString) {
    try {
        Date date = mDateFormatter.parse(dateString);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return matchesOurDatePattern(dateString);    //added my method
    }
    catch (ParseException e) {
        return false;
    }
}

/**
 * This will check if the provided string matches our date format
 * @param dateString
 * @return true if the passed string matches format 2014-1-15 (YYYY-MM-dd)
 */
private boolean matchesDatePattern(String dateString) {
    return dateString.matches("^\\d+\\-\\d+\\-\\d+");
}

4

Ich empfehle Ihnen, org.apache.commons.validator.GenericValidatorKlasse von Apache zu verwenden.

GenericValidator.isDate(String value, String datePattern, boolean strict);

Hinweis: streng - Gibt an, ob eine genaue Übereinstimmung mit dem Datumsmuster vorliegen soll.


4

Ich denke, am einfachsten ist es, eine Zeichenfolge in ein Datumsobjekt zu konvertieren und sie wieder in eine Zeichenfolge zu konvertieren. Die angegebene Datumszeichenfolge ist in Ordnung, wenn beide Zeichenfolgen noch übereinstimmen.

public boolean isDateValid(String dateString, String pattern)
{   
    try
    {
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        if (sdf.format(sdf.parse(dateString)).equals(dateString))
            return true;
    }
    catch (ParseException pe) {}

    return false;
}

2

Angenommen, beide sind Zeichenfolgen (andernfalls wären sie bereits gültige Daten), gibt es eine Möglichkeit:

package cruft;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class DateValidator
{
    private static final DateFormat DEFAULT_FORMATTER;

    static
    {
        DEFAULT_FORMATTER = new SimpleDateFormat("dd-MM-yyyy");
        DEFAULT_FORMATTER.setLenient(false);
    }

    public static void main(String[] args)
    {
        for (String dateString : args)
        {
            try
            {
                System.out.println("arg: " + dateString + " date: " + convertDateString(dateString));
            }
            catch (ParseException e)
            {
                System.out.println("could not parse " + dateString);
            }
        }
    }

    public static Date convertDateString(String dateString) throws ParseException
    {
        return DEFAULT_FORMATTER.parse(dateString);
    }
}

Hier ist die Ausgabe, die ich bekomme:

java cruft.DateValidator 32-11-2010 31-02-2010 04-01-2011
could not parse 32-11-2010
could not parse 31-02-2010
arg: 04-01-2011 date: Tue Jan 04 00:00:00 EST 2011

Process finished with exit code 0

Wie Sie sehen können, werden beide Fälle gut behandelt.


@duffymo die zweite Aussage löst keine Ausnahme aus ... :(
maximus

@Pangaea Nicht wirklich .... versuchen Sie dieses Datum "31-01-2010" es wird keine Ausnahme auslösen .......... Führen Sie es einfach auf Ihrem Computer aus und sehen Sie ... es nicht Arbeit ....
Sasidhar

Mein Fehler. Ich habe meinen Kommentar entfernt. Aber die zweite Aussage löst für mich eine Ausnahme aus. @duffymo - welches jvm benutzt du?
Aravind Yarram

@Pangaea Ich benutze jdk1.6.0_23 Ich habe dies mit diesem sogar joda-time.sourceforge.net versucht, aber selbst das hat nicht funktioniert ....
sasidhar

1
Ich verstehe, dass dies nur ein einfacher Test ist, aber um sicherzustellen, dass die Leute dieses Wort nicht wörtlich kopieren, möchte ich sagen, dass "DateFormat" NICHT GEWINDESICHER ist. Erstellen Sie es also immer als lokale Variable oder verwenden Sie es mit thread local.
Aravind Yarram

2

Das funktioniert großartig für mich. Der oben von Ben vorgeschlagene Ansatz.

private static boolean isDateValid(String s) {
    SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
    try {
        Date d = asDate(s);
        if (sdf.format(d).equals(s)) {
            return true;
        } else {
            return false;
        }
    } catch (ParseException e) {
        return false;
    }
}

1
kann asDate nicht erkennen. Was ist das?
Susheel

2

Es sieht so aus, als würde SimpleDateFormat das Muster auch nach setLenient (false) nicht streng überprüfen. Die Methode wird darauf angewendet, daher habe ich die folgende Methode verwendet, um zu überprüfen, ob das eingegebene Datum ein gültiges Datum ist oder nicht, wie im angegebenen Muster angegeben.

import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
public boolean isValidFormat(String dateString, String pattern) {
    boolean valid = true;
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
    try {
        formatter.parse(dateString);
    } catch (DateTimeParseException e) {
        valid = false;
    }
    return valid;
}

1

Zwei Kommentare zur Verwendung von SimpleDateFormat.

Es sollte als statische Instanz deklariert werden, wenn es als statischer Zugriff deklariert wurde, sollte synchronisiert werden, da es nicht threadsicher ist

IME, das ist besser als das Instanziieren einer Instanz für jede Analyse eines Datums.


guter Punkt Tom. Ich habe das von mir bereitgestellte Beispiel aktualisiert, um sicherzustellen, dass die statische Instanz konsistent verwendet wird.
Verspätung

Die Verwendung einer synchronisierten Funktion ist für einige Projekte möglicherweise nicht skalierbar. Ich würde empfehlen, das SimpleDateFormat in eine ThreadLocal-Variable anstelle einer statischen Variablen einzufügen, auf die über eine synchronisierte Funktion zugegriffen wird.
user327961

0

Die oben genannten Methoden zum Parsen von Datumsangaben sind nett. Ich habe gerade eine neue Überprüfung in vorhandenen Methoden hinzugefügt, die das konvertierte Datum mit dem ursprünglichen Datum mithilfe des Formatierers überprüfen. Es funktioniert also für fast jeden Fall, wie ich überprüft habe. zB 29.02.2013 ist ungültiges Datum. Bei gegebener Funktion wird das Datum gemäß den aktuell akzeptablen Datumsformaten analysiert. Es gibt true zurück, wenn das Datum nicht erfolgreich analysiert wurde.

 public final boolean validateDateFormat(final String date) {
        String[] formatStrings = {"MM/dd/yyyy"};
        boolean isInvalidFormat = false;
        Date dateObj;
        for (String formatString : formatStrings) {
            try {
                SimpleDateFormat sdf = (SimpleDateFormat) DateFormat.getDateInstance();
                sdf.applyPattern(formatString);
                sdf.setLenient(false);
                dateObj = sdf.parse(date);
                System.out.println(dateObj);
                if (date.equals(sdf.format(dateObj))) {
                    isInvalidFormat = false;
                    break;
                }
            } catch (ParseException e) {
                isInvalidFormat = true;
            }
        }
        return isInvalidFormat;
    }

0

Folgendes habe ich für die Knotenumgebung ohne externe Bibliotheken getan:

Date.prototype.yyyymmdd = function() {
   var yyyy = this.getFullYear().toString();
   var mm = (this.getMonth()+1).toString(); // getMonth() is zero-based
   var dd  = this.getDate().toString();
   return zeroPad([yyyy, mm, dd].join('-'));  
};

function zeroPad(date_string) {
   var dt = date_string.split('-');
   return dt[0] + '-' + (dt[1][1]?dt[1]:"0"+dt[1][0]) + '-' + (dt[2][1]?dt[2]:"0"+dt[2][0]);
}

function isDateCorrect(in_string) {
   if (!matchesDatePattern) return false;
   in_string = zeroPad(in_string);
   try {
      var idate = new Date(in_string);
      var out_string = idate.yyyymmdd();
      return in_string == out_string;
   } catch(err) {
      return false;
   }

   function matchesDatePattern(date_string) {
      var dateFormat = /[0-9]+-[0-9]+-[0-9]+/;
      return dateFormat.test(date_string); 
   }
}

Und so geht's:

isDateCorrect('2014-02-23')
true

0
// to return valid days of month, according to month and year
int returnDaysofMonth(int month, int year) {
    int daysInMonth;
    boolean leapYear;
    leapYear = checkLeap(year);
    if (month == 4 || month == 6 || month == 9 || month == 11)
        daysInMonth = 30;
    else if (month == 2)
        daysInMonth = (leapYear) ? 29 : 28;
    else
        daysInMonth = 31;
    return daysInMonth;
}

// to check a year is leap or not
private boolean checkLeap(int year) {
    Calendar cal = Calendar.getInstance();
    cal.set(Calendar.YEAR, year);
    return cal.getActualMaximum(Calendar.DAY_OF_YEAR) > 365;
}

0

Hier würde ich das Datumsformat überprüfen:

 public static boolean checkFormat(String dateTimeString) {
    return dateTimeString.matches("^\\d{4}-\\d{2}-\\d{2}") || dateTimeString.matches("^\\d{4}-\\d{2}-\\d{2}\\s\\d{2}:\\d{2}:\\d{2}")
            || dateTimeString.matches("^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}") || dateTimeString
            .matches("^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z") ||
            dateTimeString.matches("^\\d{4}-\\d{2}-\\d{2}\\s\\d{2}:\\d{2}:\\d{2}Z");
}

Wir haben jetzt die modernen java.time- Klassen für diese Arbeit. Das Schreiben komplizierter Regex ist wahrscheinlich nicht die beste Verwendung Ihrer Zeit. Siehe den Einzeiler in meiner Antwort .
Basil Bourque

0
        public static String detectDateFormat(String inputDate, String requiredFormat) {
        String tempDate = inputDate.replace("/", "").replace("-", "").replace(" ", "");
        String dateFormat;

        if (tempDate.matches("([0-12]{2})([0-31]{2})([0-9]{4})")) {
            dateFormat = "MMddyyyy";
        } else if (tempDate.matches("([0-31]{2})([0-12]{2})([0-9]{4})")) {
            dateFormat = "ddMMyyyy";
        } else if (tempDate.matches("([0-9]{4})([0-12]{2})([0-31]{2})")) {
            dateFormat = "yyyyMMdd";
        } else if (tempDate.matches("([0-9]{4})([0-31]{2})([0-12]{2})")) {
            dateFormat = "yyyyddMM";
        } else if (tempDate.matches("([0-31]{2})([a-z]{3})([0-9]{4})")) {
            dateFormat = "ddMMMyyyy";
        } else if (tempDate.matches("([a-z]{3})([0-31]{2})([0-9]{4})")) {
            dateFormat = "MMMddyyyy";
        } else if (tempDate.matches("([0-9]{4})([a-z]{3})([0-31]{2})")) {
            dateFormat = "yyyyMMMdd";
        } else if (tempDate.matches("([0-9]{4})([0-31]{2})([a-z]{3})")) {
            dateFormat = "yyyyddMMM";
        } else {
            return "Pattern Not Added";
//add your required regex
        }
        try {
            String formattedDate = new SimpleDateFormat(requiredFormat, Locale.ENGLISH).format(new SimpleDateFormat(dateFormat).parse(tempDate));

            return formattedDate;
        } catch (Exception e) {
            //
            return "";
        }

    }

0

Mit dem 'Legacy'-Datumsformat können wir das Ergebnis formatieren und mit der Quelle vergleichen.

    public boolean isValidFormat(String source, String pattern) {
    SimpleDateFormat sd = new SimpleDateFormat(pattern);
    sd.setLenient(false);
    try {
        Date date = sd.parse(source);
        return date != null && sd.format(date).equals(source);
    } catch (Exception e) {
        return false;
    }
}

Dieser Execerpt sagt 'false' zu source = 01.01.04 mit dem Muster '01 .01.2004 '


-1

setLenient auf false, wenn Sie eine strikte Validierung wünschen

public boolean isThisDateValid(String dateToValidate, String dateFromat){

    if(dateToValidate == null){
        return false;
    }

    SimpleDateFormat sdf = new SimpleDateFormat(dateFromat);
    sdf.setLenient(false);

    try {

        //if not valid, it will throw ParseException
        Date date = sdf.parse(dateToValidate);
        System.out.println(date);

    } catch (ParseException e) {

        e.printStackTrace();
        return false;
    }

    return true;
}
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.