Search code examples
javajava.util.scannerinstantiationlocaldatedatetimeformatter

How to pass LocalDate type as parameter via scanner?


I would like to instantiate an object of another class via scanner, but one of the parameters I need to pass is a LocalDate type. This is why I created a method in my main class in order to

  • ask the user for a String input in a given order (for example dd. MMM. yyyy)
  • my program then takes that input and saves it as string to display it back to the user later on

But I'm stuck with an error. Below is my birthday class and the relevant parts of my main class.

Birthday.java:

public class Birthday {
    String name;
    LocalDate date;
    int age;
    boolean gift;

    public Birthday(String name, LocalDate date, int age, boolean gift) {
        this.name = name;
        this.date = date;
        this.age = age;
        this.gift = gift;
    }
}

Main.java:

public static void addBirthday(){
        Scanner scan = new Scanner(System.in);
        //below I want to instantiate a Birthday obj
        Birthday bday = new Birthday(scan.nextLine(), addDate(), scan.nextInt(), scan.nextBoolean());
        
        bdays.add(bday); //this is referring to an ArrayList I didn't include in this excerpt   
        scan.close();
    }

...

 public static String addDate() {
        Scanner scan = new Scanner(System.in);
        LocalDate ld = LocalDate.of(scan.nextInt(), scan.nextInt(), scan.nextInt());
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd. MMM. yyyy");
        System.out.println(ld.format(dtf));
        scan.close();
        //return addedDate??;
    }

the error I keep getting for the instantiation is "incompatible types: java.lang.String cannot be converted to java.time.LocalDate", making the addDate() Method void leads to another error saying the method can't be used.

the commented out return statement is what I thought could be possible: printing out System.out.println(ld.format(dtf)); and storing it in a String called addedDate? But seems like a very wrong thought process on my part, so in the end I'm wondering if my approach in the addDate() method where I ask for year/month/day separately is what's making it wrong?


Solution

  • The type of the second parameter – named date – in the Birthday class constructor is LocalDate.

    The type of the value returned by method addDate() is String.

    A String is not a LocalDate.

    Hence you can't use the return value of method addDate() as a parameter value when calling Birthday constructor – which is exactly what the error message is telling you.

    There are several ways to resolve this problem. I suggest changing the return type of method addDate() to LocalDate.

    Rather than asking the user to enter three integers, ask him to enter a date string with your required format. Then convert that string to a LocalDate and return that value.

    public static LocalDate addDate() {
        Scanner scan = new Scanner(System.in);
        System.out.print("Enter a date [dd. MMM. yyyy]: ");
        String str = scan.nextLine();
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd. MMM. yyyy");
        return LocalDate.parse(str, dtf);
    }
    

    By the way, you should not close a Scanner that wraps the standard input. Rather than creating Scanner objects in each method in class Main, declare a static class member.

    public class Main {
        private static final Scanner scan = new Scanner(System.in);
    
        public static void addBirthday() {
            System.out.print("Name: ");
            String name = scan.nextLine();
            Birthday bday = new Birthday(name, addDate(), scan.nextInt(), scan.nextBoolean());
        }
    }