I am trying to make this code run properly. If I enter a date of birth wrong first, the program returns me null, if I enter the dob correctly from the first time it returns the correct dob. What I am doing wrong?
public static Date convertDOB() { //Date of Birth Method
System.out.println("Enter Date Of Birth: ");
String dob = in.nextLine();
SimpleDateFormat formater = new SimpleDateFormat("dd/MM/yyyy");
Date realdob = null;
try {
realdob = formater.parse(dob);
} catch (ParseException e) {
System.out.println("In-correct format. Format should be dd/mm/yyyy");
convertDOB();
}
return realdob;
}
You are initialising a new object of type Date during every recursive call. So even in subsequent recursive calls of the method, if the correct DOB is present, the first call of the method always returns null, since that's what was initialised. Instead in the catch block return the DOB you are getting from the very next call-
public static Date convertDOB() //Date of Birth Method
{
System.out.println("Enter Date Of Birth: ");
String dob = in.nextLine();
SimpleDateFormat formater = new SimpleDateFormat("dd/MM/yyyy");
Date realdob = null;
try
{
realdob = formater.parse(dob);
}
catch(ParseException e)
{
System.out.println("In-correct format. Format should be dd/mm/yyyy");
return convertDOB();
}
return realdob;
}
When you enter the wrong DOB for the first time, you fall into the catch. There, you execute the convertDOB(), but you do not return it: The first realdob is null.
Once it's done with the second convertDOB(), it continues to return realdob;, which from the above, is null. There are two ways you can fix this:
1.
catch(ParseException e)
{
System.out.println("In-correct format. Format should be dd/mm/yyyy");
return convertDOB();
}
You return whatever the convertDOB in the second execution of the function gives back.
2.
catch(ParseException e)
{
System.out.println("In-correct format. Format should be dd/mm/yyyy");
realdob = convertDOB();
}
return realdob;
You set the second convertDOB() execution to your variable, and return it afterwards.
I strongly recommend using java.time, the modern Java date and time API, for your date work. And for reading a date from the user I suggest an iterative rather than a recursive method:
static DateTimeFormatter formatter = DateTimeFormatter.ofPattern("d/M/u");
public static LocalDate convertDob() // Date of birth method
{
LocalDate realdob = null;
do {
System.out.println("Enter date of birth:");
String dob = in.nextLine();
try {
realdob = LocalDate.parse(dob, formatter);
} catch (DateTimeParseException e) {
System.out.println("In-correct format. Format should be dd/mm/yyyy");
}
} while (realdob == null);
return realdob;
}
Example interaction:
Enter date of birth:
3208/1932
In-correct format. Format should be dd/mm/yyyy
Enter date of birth:
23/08/1932
The loop condition realdob == null makes sure that the method can never return null. In the format pattern string I give only one d and one M so that the user is free to enter one digit or two digits. Many users find this convenient. If you insist on the user typing two digits for day of month and month, use pattern dd/MM/uuuu.
If you prefer a recursive solution:
public static LocalDate convertDob() // Date of birth method
{
LocalDate realdob = null;
System.out.println("Enter date of birth:");
String dob = in.nextLine();
try
{
realdob = LocalDate.parse(dob, formatter);
}
catch(DateTimeParseException e)
{
System.out.println("In-correct format. Format should be dd/mm/yyyy");
realdob = convertDob();
}
return realdob;
}
The trick compared to your code is to assign the value returned from the recursive call to realdob so it gets returned (from this invocation too).
Oracle tutorial: Date Time explaining how to use java.time.