Sjekk om en streng er en gyldig dato i Java

1. Introduksjon

I denne opplæringen vil vi diskutere de forskjellige måtene å sjekke om en String inneholder en gyldig dato i Java.

Vi diskuterer løsningene før Java 8, etter Java 8 og bruk av Apache Commons Validator.

2. Oversikt over datovalidering

Når vi mottar data i en hvilken som helst applikasjon, må vi bekrefte at de er gyldige før vi fortsetter behandlingen.

Når det gjelder datoinndata, kan det hende vi må verifisere følgende:

  • Inndataene inneholder datoen i et gyldig format, for eksempel MM / DD / ÅÅÅÅ
  • De forskjellige delene av inngangen er i et gyldig område
  • Inndataene løses til en gyldig dato i kalenderen

Vi kan bruke vanlige uttrykk for å gjøre det ovenfor. Imidlertid er vanlige uttrykk for å håndtere forskjellige inngangsformater og lokaliteter komplekse og feilutsatte. I tillegg kan de forringe ytelsen.

Vi diskuterer de forskjellige måtene å implementere datovalideringer på en fleksibel, robust og effektiv måte.

La oss først skrive et grensesnitt for datovalidering:

offentlig grensesnitt DateValidator {boolean isValid (String dateStr); }

I de neste avsnittene implementerer vi dette grensesnittet ved hjelp av de forskjellige tilnærmingene.

3. Valider med bruk DateFormat

Java har gitt fasiliteter for å formatere og analysere datoer siden begynnelsen. Denne funksjonaliteten er i DateFormat abstrakt klasse og gjennomføring - SimpleDateFormat.

La oss implementere datavalidering ved hjelp av analysere metoden for DateFormat klasse:

offentlig klasse DateValidatorUsingDateFormat implementerer DateValidator {private String dateFormat; public DateValidatorUsingDateFormat (String dateFormat) {this.dateFormat = dateFormat; } @Override public boolean isValid (String dateStr) {DateFormat sdf = new SimpleDateFormat (this.dateFormat); sdf.setLenient (false); prøv {sdf.parse (dateStr); } fange (ParseException e) {return false; } returner sant; }}

Siden de DateFormat og relaterte klasser er ikke trådsikre, lager vi en ny forekomst for hver metodeanrop.

La oss deretter skrive enhetstesten for denne klassen:

DateValidator validator = ny DateValidatorUsingDateFormat ("MM / dd / åååå"); assertTrue (validator.isValid ("02/28/2019")); assertFalse (validator.isValid ("02/30/2019"));

Dette har vært den vanligste løsningen før Java 8.

4. Valider med bruk LocalDate

Java 8 introduserte en forbedret Date and Time API. Det la til LocalDate klasse, som representerer datoen uten tid. Denne klassen er uforanderlig og trådsikker.

LocalDate gir to statiske metoder for å analysere datoer. Begge to bruker en DateTimeFormatter å gjøre selve analyseringen:

offentlig statisk LocalDate-analyse (CharSequence-tekst) // analyserer datoer ved bruk av DateTimeFormatter.ISO_LOCAL_DATE offentlig statisk LocalDate-analyse (CharSequence-tekst, DateTimeFormatter-formater) // analyserer datoer ved hjelp av den angitte formateringen

La oss bruke analysere metode for å implementere datavalidering:

offentlig klasse DateValidatorUsingLocalDate implementerer DateValidator {private DateTimeFormatter dateFormatter; public DateValidatorUsingLocalDate (DateTimeFormatter dateFormatter) {this.dateFormatter = dateFormatter; } @ Override public boolean isValid (String dateStr) {prøv {LocalDate.parse (dateStr, this.dateFormatter); } catch (DateTimeParseException e) {return false; } returner sant; }}

Implementeringen bruker en DateTimeFormatter objekt for formatering. Siden denne klassen er trådsikker, bruker vi den samme forekomsten på tvers av forskjellige metodeanrop.

La oss også legge til en enhetstest for denne implementeringen:

DateTimeFormatter dateFormatter = DateTimeFormatter.BASIC_ISO_DATE; DateValidator validator = ny DateValidatorUsingLocalDate (dateFormatter); assertTrue (validator.isValid ("20190228")); assertFalse (validator.isValid ("20190230"));

5. Valider med bruk DateTimeFormatter

I forrige avsnitt så vi det LocalDate bruker en DateTimeFormatter objekt for parsing. Vi kan også bruke DateTimeFormatter klasse direkte for formatering og parsing.

DateTimeFormatter analyserer en tekst i to faser. I fase 1 analyserer den teksten i forskjellige dato- og tidsfelt basert på konfigurasjonen. I fase 2 løser den de analyserte feltene til et dato- og / eller tidsobjekt.

De ResolverStyle attributt kontroller fase 2. Det er en enum har tre mulige verdier:

  • LENIENT - løser datoer og tider mildt
  • SMART - løser datoer og klokkeslett på en intelligent måte
  • STRENG - løser strengt datoer og klokkeslett

La oss nå skrive datavalidering ved hjelp av DateTimeFormatter direkte:

offentlig klasse DateValidatorUsingDateTimeFormatter implementerer DateValidator {private DateTimeFormatter dateFormatter; public DateValidatorUsingDateTimeFormatter (DateTimeFormatter dateFormatter) {this.dateFormatter = dateFormatter; } @Override public boolean isValid (String dateStr) {prøv {this.dateFormatter.parse (dateStr); } catch (DateTimeParseException e) {return false; } returner sant; }}

La oss deretter legge til enhetstesten for denne klassen:

DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern ("uuuu-MM-dd", Locale.US) .withResolverStyle (ResolverStyle.STRICT); DateValidator validator = ny DateValidatorUsingDateTimeFormatter (dateFormatter); assertTrue (validator.isValid ("2019-02-28")); assertFalse (validator.isValid ("2019-02-30"));

I testen ovenfor oppretter vi en DateTimeFormatter basert på mønster og lokalitet. Vi bruker den strenge oppløsningen for datoer.

6. Valider med Apache Commons Validator

Apache Commons-prosjektet gir et valideringsrammeverk. Dette inneholder valideringsrutiner, som dato, klokkeslett, tall, valuta, IP-adresse, e-postadresse og URL.

For vårt mål i denne artikkelen, la oss ta en titt på GenericValidator klasse, som gir et par metoder for å sjekke om en String inneholder en gyldig dato:

public static boolean isDate (String value, Locale locale) public static boolean isDate (String value, String datePattern, boolean strict)

For å bruke biblioteket, la oss legge til commons-validator Maven avhengighet av prosjektet vårt:

 commons-validator commons-validator 1.6 

La oss deretter bruke GenericValidator klasse for å validere datoer:

assertTrue (GenericValidator.isDate ("2019-02-28", "åååå-MM-dd", sant)); assertFalse (GenericValidator.isDate ("2019-02-29", "åååå-MM-dd", sant));

7. Konklusjon

I denne artikkelen så vi på de forskjellige måtene å sjekke om en String inneholder en gyldig dato.

Som vanlig finner du full kildekode på GitHub.