Vérifier si une chaîne est une date valide en Java

1. Introduction

Dans ce didacticiel, nous aborderons les différentes façons de vérifier si une chaîne contient une date valide en Java.

Nous discuterons des solutions avant Java 8, après Java 8, et en utilisant Apache Commons Validator.

2. Présentation de la validation de la date

Chaque fois que nous recevons des données dans une application, nous devons vérifier qu'elles sont valides avant de procéder à tout autre traitement.

Dans le cas des entrées de date, nous pouvons avoir besoin de vérifier les éléments suivants:

  • L'entrée contient la date dans un format valide, tel que MM / JJ / AAAA
  • Les différentes parties de l'entrée sont dans une plage valide
  • L'entrée se résout en une date valide dans le calendrier

Nous pouvons utiliser des expressions régulières pour faire ce qui précède. Cependant, les expressions régulières pour gérer divers formats d'entrée et paramètres régionaux sont complexes et sujettes aux erreurs. De plus, ils peuvent dégrader les performances.

Nous discuterons des différentes façons de mettre en œuvre les validations de date de manière flexible, robuste et efficace.

Commençons par écrire une interface pour la validation de la date:

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

Dans les sections suivantes, nous implémenterons cette interface en utilisant les différentes approches.

3. Validez à l'aide de DateFormat

Java a fourni des installations pour formater et analyser les dates depuis le début. Cette fonctionnalité se trouve dans la classe abstraite DateFormat et son implémentation - SimpleDateFormat .

Implémentons la validation de date à l'aide de la méthode parse de la classe DateFormat :

public class DateValidatorUsingDateFormat implements 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); try { sdf.parse(dateStr); } catch (ParseException e) { return false; } return true; } }

Étant donné que le DateFormat et les classes associées ne sont pas thread-safe , nous créons une nouvelle instance pour chaque appel de méthode.

Ensuite, écrivons le test unitaire pour cette classe:

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

C'était la solution la plus courante avant Java 8.

4. Validez à l'aide de LocalDate

Java 8 a introduit une API de date et d'heure améliorée. Il a ajouté la classe LocalDate , qui représente la date sans heure. Cette classe est immuable et thread-safe.

LocalDate fournit deux méthodes statiques pour analyser les dates. Les deux utilisent un DateTimeFormatter pour effectuer l'analyse réelle:

public static LocalDate parse​(CharSequence text) // parses dates using using DateTimeFormatter.ISO_LOCAL_DATE public static LocalDate parse​(CharSequence text, DateTimeFormatter formatter) // parses dates using the provided formatter

Utilisons la méthode parse pour implémenter la validation de la date:

public class DateValidatorUsingLocalDate implements DateValidator { private DateTimeFormatter dateFormatter; public DateValidatorUsingLocalDate(DateTimeFormatter dateFormatter) { this.dateFormatter = dateFormatter; } @Override public boolean isValid(String dateStr) { try { LocalDate.parse(dateStr, this.dateFormatter); } catch (DateTimeParseException e) { return false; } return true; } }

L'implémentation utilise un objet DateTimeFormatter pour la mise en forme. Comme cette classe est thread-safe, nous utilisons la même instance sur différents appels de méthode.

Ajoutons également un test unitaire pour cette implémentation:

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

5. Validez à l'aide de DateTimeFormatter

Dans la section précédente, nous avons vu que LocalDate utilise un objet DateTimeFormatter pour l'analyse. Nous pouvons également utiliser la classe DateTimeFormatter directement pour le formatage et l'analyse.

DateTimeFormatter analyse un texte en deux phases. Dans la phase 1, il analyse le texte dans divers champs de date et d'heure en fonction de la configuration. Dans la phase 2, il résout les champs analysés en un objet date et / ou heure.

L' attribut ResolverStyle contrôle la phase 2. Il s'agit d'une énumération ayant trois valeurs possibles:

  • LENIENT - résout les dates et les heures de manière indulgente
  • SMART - résout les dates et les heures de manière intelligente
  • STRICT - résout strictement les dates et heures

Maintenant, écrivons la validation de la date à l'aide de DateTimeFormatter directement:

public class DateValidatorUsingDateTimeFormatter implements DateValidator { private DateTimeFormatter dateFormatter; public DateValidatorUsingDateTimeFormatter(DateTimeFormatter dateFormatter) { this.dateFormatter = dateFormatter; } @Override public boolean isValid(String dateStr) { try { this.dateFormatter.parse(dateStr); } catch (DateTimeParseException e) { return false; } return true; } }

Ensuite, ajoutons le test unitaire pour cette classe:

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

Dans le test ci-dessus, nous créons un DateTimeFormatter basé sur le modèle et les paramètres régionaux. Nous utilisons la résolution stricte pour les dates.

6. Valider à l'aide d'Apache Commons Validator

Le projet Apache Commons fournit un cadre de validation. Cela contient des routines de validation, telles que la date, l'heure, les chiffres, la devise, l'adresse IP, l'e-mail et l'URL.

Pour notre objectif dans cet article, jetons un coup d'œil à la classe GenericValidator , qui fournit quelques méthodes pour vérifier si une chaîne contient une date valide:

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

Pour utiliser la bibliothèque, ajoutons la dépendance Maven du validateur commun à notre projet:

 commons-validator commons-validator 1.6 

Ensuite, utilisons la classe GenericValidator pour valider les dates:

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

7. Conclusion

Dans cet article, nous avons examiné les différentes façons de vérifier si une chaîne contient une date valide.

Comme d'habitude, le code source complet peut être trouvé sur GitHub.