Estoy tratando de hacer que este código se ejecute correctamente. Si ingreso una fecha de nacimiento incorrecta primero, el programa me devuelve nulo, si ingreso el dob correctamente desde la primera vez, devuelve el dob correcto. ¿Que estoy haciendo mal?
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; }Está inicializando un nuevo objeto de tipo Fecha durante cada llamada recursiva. Entonces, incluso en llamadas recursivas posteriores del método, si está presente el DOB correcto, la primera llamada del método siempre devuelve un valor nulo, ya que eso es lo que se inicializó. En cambio, en el bloque de captura, devuelva el DOB que está recibiendo de la siguiente llamada:
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; }Cuando ingresa el DOB incorrecto por primera vez, cae en la trampa. Allí, ejecuta convertDOB() , pero no lo devuelve: el primer realdob es nulo.
Una vez que se hace con el segundo convertDOB(), continúa return realdob; , que por lo anterior, es nulo. Hay dos formas de arreglar esto:
1.
catch(ParseException e) { System.out.println("In-correct format. Format should be dd/mm/yyyy"); return convertDOB(); }Devuelve lo que devuelve convertDOB en la segunda ejecución de la función.
2.
catch(ParseException e) { System.out.println("In-correct format. Format should be dd/mm/yyyy"); realdob = convertDOB(); } return realdob; Establece la segunda ejecución de convertDOB() en su variable y la devuelve después.
Recomiendo enfáticamente usar java.time, la moderna API de fecha y hora de Java, para su trabajo de fechas. Y para leer una fecha del usuario, sugiero un método iterativo en lugar de recursivo:
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; }Ejemplo de interacción:
Enter date of birth: 3208/1932 In-correct format. Format should be dd/mm/yyyy Enter date of birth: 23/08/1932 La condición de ciclo realdob == null se asegura de que el método nunca pueda devolver null . En la cadena de patrón de formato, solo doy una d y una M para que el usuario pueda ingresar uno o dos dígitos. Muchos usuarios encuentran esto conveniente. Si insiste en que el usuario escriba dos dígitos para el día del mes y el mes, use el patrón dd/MM/uuuu .
Si prefiere una solución recursiva:
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; } El truco en comparación con su código es asignar el valor devuelto por la llamada recursiva a realdob para que se devuelva (también desde esta invocación).
Tutorial de Oracle: fecha y hora que explica cómo usar java.time.