Comment valider une date avec une expression régulière

Comment valider une date avec une expression régulière

Format de date (jj / mm / aaaa) Modèle d'expression régulière

(0?[1-9]|[12][0-9]|3[01])/(0?[1-9]|1[012])/((19|20)\\d\\d)

La description

(           #start of group #1
 0?[1-9]        #  01-09 or 1-9
 |                      #  ..or
 [12][0-9]      #  10-19 or 20-29
 |          #  ..or
 3[01]          #  30, 31
)           #end of group #1
  /         #  follow by a "/"
   (            #    start of group #2
    0?[1-9]     #   01-09 or 1-9
    |           #   ..or
    1[012]      #   10,11,12
    )           #    end of group #2
     /          #   follow by a "/"
      (         #     start of group #3
       (19|20)\\d\\d    #       19[0-9][0-9] or 20[0-9][0-9]
       )        #     end of group #3

L'expression régulière ci-dessus est utilisée pour valider le format de la date en «jj / mm / aaaa», vous pouvez facilement personnaliser en fonction de vos besoins. Cependant, il est un peu difficile de valider l’année bissextile, 30 ou 31 jours par mois, nous pouvons avoir besoin d’une logique de base comme ci-dessous.

P.S Do let me know, if you know the regular expression which can check the leap and days of a month.

Exemple d'expression régulière Java

package com.example.regex;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class DateValidator{

  private Pattern pattern;
  private Matcher matcher;

  private static final String DATE_PATTERN =
          "(0?[1-9]|[12][0-9]|3[01])/(0?[1-9]|1[012])/((19|20)\\d\\d)";

  public DateValidator(){
      pattern = Pattern.compile(DATE_PATTERN);
  }

  /**
   * Validate date format with regular expression
   * @param date date address for validation
   * @return true valid date fromat, false invalid date format
   */
   public boolean validate(final String date){

     matcher = pattern.matcher(date);

     if(matcher.matches()){

     matcher.reset();

     if(matcher.find()){

             String day = matcher.group(1);
         String month = matcher.group(2);
         int year = Integer.parseInt(matcher.group(3));

         if (day.equals("31") &&
          (month.equals("4") || month .equals("6") || month.equals("9") ||
                  month.equals("11") || month.equals("04") || month .equals("06") ||
                  month.equals("09"))) {
            return false; // only 1,3,5,7,8,10,12 has 31 days
         } else if (month.equals("2") || month.equals("02")) {
                  //leap year
          if(year % 4==0){
              if(day.equals("30") || day.equals("31")){
                  return false;
              }else{
                  return true;
              }
          }else{
                 if(day.equals("29")||day.equals("30")||day.equals("31")){
                  return false;
                 }else{
                  return true;
              }
          }
          }else{
        return true;
          }
       }else{
              return false;
       }
     }else{
      return false;
     }
   }
}

Format de date correspondant:

1. “1/1/2010” , “01/01/2020”
2. “31/1/2010”, “31/01/2020”
3. “29/2/2008”, “29/02/2008”
4. “28/2/2009”, “28/02/2009”
5. “31/3/2010”, “31/03/2010”
6. “30/4/2010”, “30/04/2010”
7. “31/5/2010”, “31/05/2010”
8. “30/6/2010”, “30/06/2010”
9. “31/7/2010”, “31/07/2010”
10. “31/8/2010”, “31/08/2010”
11. “30/9/2010”, “30/09/2010”
12. “31/10/2010”, “31/10/2010”
13. “30/11/2010”, “30/11/2010”
14. “31/12/2010”, “31/12/2010”

Le format de la date ne correspond pas:

1. “32/1/2010” , “32/01/2020” – day is out of range [1-31]
2. “1/13/2010”, “01/01/1820” – month is out of range [1-12], year is out of range [1900-2999]
3. “29/2/2007”, “29/02/2007” – 2007 is not leap year, only has 28 days
4. “30/2/2008”, “31/02/2008” – leap year in February has 29 days only
5. “29/a/2008”, “a/02/2008” – month is invalid, day is invalid
6. “333/2/2008”, “29/02/200a” – day is invalid, year is invalid
7. “31/4/20100”, “31/04/2010” – April has 30 days only
8. “31/6/2010”, “31/06/2010” -June has 30 days only
9. “31/9/2010”, “31/09/2010” – September has 30 days only
10. “31/11/2010” – November has 30 days only

Test unitaire - DateValidatorTest

package com.example.regex;

import org.testng.Assert;
import org.testng.annotations.*;

/**
 * Date format dd/mm/yyyy validator Testing
 * @author example
 *
 */
public class DateValidatorTest {

    private DateValidator dateValidator;

    @BeforeClass
        public void initData(){
        dateValidator = new DateValidator();
        }

    @DataProvider
    public Object[][] ValidDateProvider() {
        return new Object[][]{
            new Object[] {"1/1/2010"}, new Object[] {"01/01/2020"},
            new Object[] {"31/1/2010"}, new Object[] {"31/01/2020"},
            new Object[] {"29/2/2008"}, new Object[] {"29/02/2008"},
            new Object[] {"28/2/2009"}, new Object[] {"28/02/2009"},
            new Object[] {"31/3/2010"}, new Object[] {"31/03/2010"},
            new Object[] {"30/4/2010"}, new Object[] {"30/04/2010"},
            new Object[] {"31/5/2010"}, new Object[] {"31/05/2010"},
            new Object[] {"30/6/2010"}, new Object[] {"30/06/2010"},
            new Object[] {"31/7/2010"}, new Object[] {"31/07/2010"},
            new Object[] {"31/8/2010"}, new Object[] {"31/08/2010"},
            new Object[] {"30/9/2010"}, new Object[] {"30/09/2010"},
            new Object[] {"31/10/2010"}, new Object[] {"31/10/2010"},
            new Object[] {"30/11/2010"}, new Object[] {"30/11/2010"},
            new Object[] {"31/12/2010"}, new Object[] {"31/12/2010"}
        };
    }

    @DataProvider
    public Object[][] InvalidDateProvider() {
        return new Object[][]{
            new Object[] {"32/1/2010"}, new Object[] {"32/01/2020"},
            new Object[] {"1/13/2010"}, new Object[] {"01/01/1820"},
            new Object[] {"29/2/2007"}, new Object[] {"29/02/2007"},
            new Object[] {"30/2/2008"}, new Object[] {"31/02/2008"},
            new Object[] {"29/a/2008"}, new Object[] {"a/02/2008"},
            new Object[] {"333/2/2008"}, new Object[] {"29/02/200a"},
            new Object[] {"31/4/2010"}, new Object[] {"31/04/2010"},
            new Object[] {"31/6/2010"}, new Object[] {"31/06/2010"},
            new Object[] {"31/9/2010"}, new Object[] {"31/09/2010"},
            new Object[] {"31/11/2010"}
        };
    }

    @Test(dataProvider = "ValidDateProvider")
    public void ValidDateTest(String date) {
        boolean valid = dateValidator.validate(date);
        System.out.println("Date is valid : " + date + " , " + valid);
        Assert.assertEquals(true, valid);
    }

    @Test(dataProvider = "InvalidDateProvider",
                 dependsOnMethods="ValidDateTest")
    public void InValidDateTest(String date) {
        boolean valid = dateValidator.validate(date);
        System.out.println("Date is valid : " + date + " , " + valid);
        Assert.assertEquals(false, valid);
    }
}

Test unitaire - Résultat

[Parser] Running:
  E:\workspace\example\temp-testng-customsuite.xml

Date is valid : 1/1/2010 , true
Date is valid : 01/01/2020 , true
Date is valid : 31/1/2010 , true
Date is valid : 31/01/2020 , true
Date is valid : 29/2/2008 , true
Date is valid : 29/02/2008 , true
Date is valid : 28/2/2009 , true
Date is valid : 28/02/2009 , true
Date is valid : 31/3/2010 , true
Date is valid : 31/03/2010 , true
Date is valid : 30/4/2010 , true
Date is valid : 30/04/2010 , true
Date is valid : 31/5/2010 , true
Date is valid : 31/05/2010 , true
Date is valid : 30/6/2010 , true
Date is valid : 30/06/2010 , true
Date is valid : 31/7/2010 , true
Date is valid : 31/07/2010 , true
Date is valid : 31/8/2010 , true
Date is valid : 31/08/2010 , true
Date is valid : 30/9/2010 , true
Date is valid : 30/09/2010 , true
Date is valid : 31/10/2010 , true
Date is valid : 31/10/2010 , true
Date is valid : 30/11/2010 , true
Date is valid : 30/11/2010 , true
Date is valid : 31/12/2010 , true
Date is valid : 31/12/2010 , true
Date is valid : 32/1/2010 , false
Date is valid : 32/01/2020 , false
Date is valid : 1/13/2010 , false
Date is valid : 01/01/1820 , false
Date is valid : 29/2/2007 , false
Date is valid : 29/02/2007 , false
Date is valid : 30/2/2008 , false
Date is valid : 31/02/2008 , false
Date is valid : 29/a/2008 , false
Date is valid : a/02/2008 , false
Date is valid : 333/2/2008 , false
Date is valid : 29/02/200a , false
Date is valid : 31/4/2010 , false
Date is valid : 31/04/2010 , false
Date is valid : 31/6/2010 , false
Date is valid : 31/06/2010 , false
Date is valid : 31/9/2010 , false
Date is valid : 31/09/2010 , false
Date is valid : 31/11/2010 , false
PASSED: ValidDateTest("1/1/2010")
PASSED: ValidDateTest("01/01/2020")
PASSED: ValidDateTest("31/1/2010")
PASSED: ValidDateTest("31/01/2020")
PASSED: ValidDateTest("29/2/2008")
PASSED: ValidDateTest("29/02/2008")
PASSED: ValidDateTest("28/2/2009")
PASSED: ValidDateTest("28/02/2009")
PASSED: ValidDateTest("31/3/2010")
PASSED: ValidDateTest("31/03/2010")
PASSED: ValidDateTest("30/4/2010")
PASSED: ValidDateTest("30/04/2010")
PASSED: ValidDateTest("31/5/2010")
PASSED: ValidDateTest("31/05/2010")
PASSED: ValidDateTest("30/6/2010")
PASSED: ValidDateTest("30/06/2010")
PASSED: ValidDateTest("31/7/2010")
PASSED: ValidDateTest("31/07/2010")
PASSED: ValidDateTest("31/8/2010")
PASSED: ValidDateTest("31/08/2010")
PASSED: ValidDateTest("30/9/2010")
PASSED: ValidDateTest("30/09/2010")
PASSED: ValidDateTest("31/10/2010")
PASSED: ValidDateTest("31/10/2010")
PASSED: ValidDateTest("30/11/2010")
PASSED: ValidDateTest("30/11/2010")
PASSED: ValidDateTest("31/12/2010")
PASSED: ValidDateTest("31/12/2010")
PASSED: InValidDateTest("32/1/2010")
PASSED: InValidDateTest("32/01/2020")
PASSED: InValidDateTest("1/13/2010")
PASSED: InValidDateTest("01/01/1820")
PASSED: InValidDateTest("29/2/2007")
PASSED: InValidDateTest("29/02/2007")
PASSED: InValidDateTest("30/2/2008")
PASSED: InValidDateTest("31/02/2008")
PASSED: InValidDateTest("29/a/2008")
PASSED: InValidDateTest("a/02/2008")
PASSED: InValidDateTest("333/2/2008")
PASSED: InValidDateTest("29/02/200a")
PASSED: InValidDateTest("31/4/2010")
PASSED: InValidDateTest("31/04/2010")
PASSED: InValidDateTest("31/6/2010")
PASSED: InValidDateTest("31/06/2010")
PASSED: InValidDateTest("31/9/2010")
PASSED: InValidDateTest("31/09/2010")
PASSED: InValidDateTest("31/11/2010")

===============================================
    com.example.regex.DateValidatorTest
    Tests run: 47, Failures: 0, Skips: 0
===============================================

===============================================
example
Total tests run: 47, Failures: 0, Skips: 0
===============================================

Vous voulez en savoir plus sur les expressions régulières? Je recommande vivement ce meilleur livre classique - «Maîtriser l'expression régulière»

+
+