Check if date is Valid java

Viewed 1573

I'm trying to make a method in java to check if a date is valid Format MM/dd/yyyy

public static boolean checkDate(String date)
{
    Calendar cal = Calendar.getInstance();
    int year=0,month=0,day=0;
    int year2;

    year=Integer.parseInt(date.substring(6));
    day=Integer.parseInt(date.substring(3,5));
    month=Integer.parseInt(date.substring(0,2));

    year2=cal.get(Calendar.YEAR);

    if(date.length() != 10)
        return false;
    if(year==year2||year<=year2-100)
        return true;
    else if(month>12||month<1)
        return true;
    else if(day<1)
        return true;
    else if(month==2&&day>28)
        return true;
    else if((month==1||month==3||month==5||month==7||month==8||month==10||month==12)&&day>31)
        return true;
    else if((month!=1||month!=3||month!=5||month!=7||month!=8||month!=10||month!=12)&&day>31)
        return true;
    else
        return false;
}

For some reason its not working and I have no idea why. If anyone can see if I made a simple mistake please let me know.

4 Answers

tl;dr

try 
{
    LocalDate ld = 
        LocalDate.parse( 
            "01/23/2021" , 
            DateTimeFormatter.ofPattern( "MM/dd/uuuu" )
        ) 
    ;
}
catch ( DateTimeFormatException e )
{
    … handle faulty input
}

java.time.LocalDate and DateTimeFormatException

Never use the terrible date-time classes such as Calendar and Date. Use only the modern java.time classes defined by JSR 310.

Define a formatting pattern to match your inputs.

DateTimeFormatter f = DateTimeFormatter.ofPattern( "MM/dd/uuuu" ) ;

Parse your input as a LocalDate object.

LocalDate ld = LocalDate.parse( input , f ) ;

Trap for the DateTimeFormatException thrown if the input is faulty.

try 
{
    LocalDate ld = LocalDate.parse( input , f ) ;
}
catch ( DateTimeFormatException e )
{
    … handle faulty input
}

About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes. Hibernate 5 & JPA 2.2 support java.time.

Where to obtain the java.time classes?

edit(adding checks for year)

Assuming you are using Java 8, The below code checks if -

  • The format is correct (MM/dd/yyyy)
  • If the year entered is less than current year
  • If the year entered is more than (current year - 100)
  • If it has 31 days, 30 days, or leap year
  • If there is any accidental strings in the input string except integers

Imports - import java.text.*; and import java.time.*;

Logic -

 private static boolean checkDate(String dateStr) {

        DateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
        sdf.setLenient(false);

        try {
          sdf.parse(dateStr);

          int currentYear = Year.now().getValue();
          String str[] = dateStr.split("/");
          int year = Integer.parseInt(str[2]);

          if(year > currentYear || year < currentYear-100){
            return false; 
          }

        } catch (NumberFormatException | ParseException ex){

          return false;  // Returns false if parsing fails (in case of bad input).
        }

        return true; // Returns true for valid date Strings
     }

Test -

        System.out.println(checkDate("02/09/2021")); // Returns false
        System.out.println(checkDate("02/09/2020")); // Returns true
        System.out.println(checkDate("02/09/1900")); // Returns false
        System.out.println(checkDate("02/31/2020")); // Returns false
        System.out.println(checkDate("11/31/2020")); // Returns false
        System.out.println(checkDate("05/23/2020")); // Returns true
        System.out.println(checkDate("abc/23/2020")); // Returns false
        System.out.println(checkDate("05/23/efg")); // Returns false
        System.out.println(checkDate("02/29/2016")); // Leap year. Returns true
        System.out.println(checkDate("02/29/2019")); // Not a Leap year. Returns false

I run your code with "01/11/2019" it returns false.

A few things I have spot in your code in function of checkDate. I am going to leave comments.

public static boolean checkDate(String date) {
          //1. Target: String date = "MM/dd/yyyy" 
          Calendar cal = Calendar.getInstance();
          int year=0, month=0, day=0;

          int year2;

          year=Integer.parseInt(date.substring(6));
          day=Integer.parseInt(date.substring(3,5));
          month=Integer.parseInt(date.substring(0,2));

          year2=cal.get(Calendar.YEAR);
          //2. this check will in the very beginning for the safety purpose, if the date string length is not 10, it will false, no need to do above work.
          if(date.length() != 10)
            return false;

          if(year==year2||year<=year2-100)
            return true;
         //3. Here is a obviously error, month is from 1 to 12, so change here to else if (month <= 12 && month >= 1)  
         else if(month>12||month<1)
            return true;

         //4. else if(day >= 1 && day <= 31) 
         else if(day<1)
            return true;

         //5. else if(month == 2 && day >= 28)
         else if(month==2&&day>28)
            return true;

         //6. else if((month==1||month==3||month==5||month==7||month==8||month==10||month==12)&&day==31)
         else if((month==1||month==3||month==5||month==7||month==8||month==10||month==12)&&day>31)
            return true; 

         //7. else if((month== 4||month==6||month==9||month==11)&& day ==30)       
         else if((month!=1||month!=3||month!=5||month!=7||month!=8||month!=10||month!=12)&&day>31)
            return true;
         else
            return false;
    }

You probably have your reasons but I suggest you using SimpleDateFormat class because you can choose the pattern and format the date as you want. Here is a really simple example similiar to what you posted so you can take a look

    Calendar cal = Calendar.getInstance();
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MM/dd/yyyy");
    System.out.println(simpleDateFormat.format(cal.getFirstDayOfWeek()));

    String s = simpleDateFormat.format(cal.getFirstDayOfWeek());
    String [] array = s.split("/");

    int year=Integer.parseInt(array[2]);
    int day=Integer.parseInt(array[1]);
    int month=Integer.parseInt(array[0]);

    if(year > 2000 && year < 2020) {
        //To Do
    }
    if(day <= 31) {
        //To Do
    }
    if(month <= 12) {
        //To Do
    }

Output :

    01/01/1970
Related