Controleer of een string een geldige datum is in Java

1. Inleiding

In deze tutorial bespreken we de verschillende manieren om te controleren of een Draad bevat een geldige datum in Java.

We bespreken de oplossingen vóór Java 8, na Java 8 en met behulp van de Apache Commons Validator.

2. Overzicht datumvalidatie

Elke keer dat we gegevens ontvangen in een applicatie, moeten we controleren of deze geldig zijn voordat we verder gaan met verwerken.

In het geval van datuminvoer, moeten we mogelijk het volgende controleren:

  • De invoer bevat de datum in een geldig formaat, zoals MM / DD / JJJJ
  • De verschillende onderdelen van de invoer vallen binnen een geldig bereik
  • De invoer wordt omgezet naar een geldige datum in de kalender

We kunnen reguliere expressies gebruiken om het bovenstaande te doen. Reguliere expressies om verschillende invoerformaten en landinstellingen te verwerken zijn echter complex en foutgevoelig. Bovendien kunnen ze de prestaties verminderen.

We bespreken de verschillende manieren om datumvalidaties op een flexibele, robuuste en efficiënte manier te implementeren.

Laten we eerst een interface schrijven voor de datumvalidatie:

openbare interface DateValidator {boolean isValid (String dateStr); }

In de volgende secties zullen we deze interface implementeren met behulp van de verschillende benaderingen.

3. Valideer met Datumnotatie

Java heeft vanaf het begin de mogelijkheid geboden om datums op te maken en te ontleden. Deze functionaliteit bevindt zich in de Datumnotatie abstracte klasse en de implementatie ervan - SimpleDateFormat.

Laten we de datumvalidatie implementeren met behulp van de ontleden methode van de Datumnotatie klasse:

openbare klasse DateValidatorUsingDateFormat implementeert DateValidator {private String dateFormat; openbare DateValidatorUsingDateFormat (String dateFormat) {this.dateFormat = dateFormat; } @Override openbare boolean isValid (String dateStr) {DateFormat sdf = nieuwe SimpleDateFormat (this.dateFormat); sdf.setLenient (false); probeer {sdf.parse (dateStr); } catch (ParseException e) {return false; } retourneren waar; }}

Sinds de Datumnotatie en gerelateerde klassen zijn niet thread-safe, maken we een nieuwe instantie voor elke methodeaanroep.

Laten we vervolgens de unit-test voor deze klasse schrijven:

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

Dit was de meest voorkomende oplossing vóór Java 8.

4. Valideer met LocalDate

Java 8 introduceerde een verbeterde datum- en tijd-API. Het voegde de LocalDate class, die de datum zonder tijd vertegenwoordigt. Deze klasse is onveranderlijk en thread-safe.

LocalDate biedt twee statische methoden om datums te ontleden. Beiden gebruiken een DateTimeFormatter om het eigenlijke parseren uit te voeren:

public static LocalDate parse (CharSequence-tekst) // parseert datums met behulp van DateTimeFormatter.ISO_LOCAL_DATE public static LocalDate parse (CharSequence-tekst, DateTimeFormatter-formatter) // parseert datums met behulp van de opgegeven formatter

Laten we de ontleden methode om de datumvalidatie te implementeren:

openbare klasse DateValidatorUsingLocalDate implementeert DateValidator {privé DateTimeFormatter dateFormatter; openbare DateValidatorUsingLocalDate (DateTimeFormatter dateFormatter) {this.dateFormatter = dateFormatter; } @Override openbare boolean isValid (String dateStr) {probeer {LocalDate.parse (dateStr, this.dateFormatter); } catch (DateTimeParseException e) {return false; } retourneren waar; }}

De implementatie maakt gebruik van een DateTimeFormatter object voor opmaak. Omdat deze klasse thread-safe is, gebruiken we dezelfde instantie voor verschillende methodeaanroepen.

Laten we ook een unit-test toevoegen voor deze implementatie:

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

5. Valideer met DateTimeFormatter

In de vorige paragraaf hebben we dat gezien LocalDate gebruikt een DateTimeFormatter object voor parsing. We kunnen ook de DateTimeFormatter class direct voor het formatteren en ontleden.

DateTimeFormatter parseert een tekst in twee fasen. In fase 1 parseert het de tekst in verschillende datum- en tijdvelden op basis van de configuratie. In fase 2 worden de ontlede velden omgezet in een datum- en / of tijdobject.

De ResolverStyle attribuutcontroles fase 2. Het is een opsomming met drie mogelijke waarden:

  • LENIENT - lost datums en tijden soepel op
  • SMART - lost datums en tijden op een intelligente manier op
  • STRIKT - lost datums en tijden strikt op

Laten we nu de datumvalidatie schrijven met DateTimeFormatter direct:

openbare klasse DateValidatorUsingDateTimeFormatter implementeert DateValidator {privé DateTimeFormatter dateFormatter; openbare DateValidatorUsingDateTimeFormatter (DateTimeFormatter dateFormatter) {this.dateFormatter = dateFormatter; } @Override openbare boolean isValid (String dateStr) {probeer {this.dateFormatter.parse (dateStr); } catch (DateTimeParseException e) {return false; } retourneren waar; }}

Laten we vervolgens de unit-test voor deze klasse toevoegen:

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

In de bovenstaande test maken we een DateTimeFormatter gebaseerd op patroon en landinstelling. We gebruiken de strikte resolutie voor datums.

6. Valideer met Apache Commons Validator

Het Apache Commons-project biedt een validatiekader. Dit bevat validatieroutines, zoals datum, tijd, cijfers, valuta, IP-adres, e-mail en URL.

Laten we voor ons doel in dit artikel eens kijken naar het GenericValidator class, die een aantal methoden biedt om te controleren of een Draad bevat een geldige datum:

public static boolean isDate (String-waarde, locale locale) public static boolean isDate (String-waarde, String datePattern, boolean strict)

Om de bibliotheek te gebruiken, voegen we het commons-validator Maven afhankelijkheid van ons project:

 commons-validator commons-validator 1.6 

Laten we vervolgens de GenericValidator klas om datums te valideren:

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

7. Conclusie

In dit artikel hebben we gekeken naar de verschillende manieren om te controleren of een Draad bevat een geldige datum.

Zoals gewoonlijk is de volledige broncode te vinden op GitHub.