0

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?

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
nasrot
  • 33
  • 1
  • 5
  • 1
    "making the `addDate()` Method void leads to another error" you shouldn't debug by guess. Think about what making that method `void` means in the context of your code. You should see by yourself that is not the way to fix your code. – Federico klez Culloca Feb 23 '21 at 12:04
  • 2
    The second parameter of your `Birthday` constructor expects a `LocalDate`. You pass `addDate()` which returns a `String`. Don't return a String if you want a `LocalDate`. – Ivar Feb 23 '21 at 12:06
  • 1
    Your `Birthday `constructor takes a `LocalDate` for its second parameter. Hence `addDate()` must have a return type of `LocalDate`. – tgdavies Feb 23 '21 at 12:07
  • @all I want to scream at my own mistake oh my god.. i can't believe THAT was basically it. Thanks folks! – nasrot Feb 23 '21 at 12:21
  • Does this answer your question? [Java string to date conversion](https://stackoverflow.com/questions/4216745/java-string-to-date-conversion) – Vicky Kapadia Feb 24 '21 at 02:07

2 Answers2

1
  1. Do not create new Scanner object in addDate()

  2. Use the already created Scanner object and simply read a String as LocalDate like LocalDate.parse(scan.next())

public static LocalDate addDate(Scanner scan) {
    return LocalDate.parse(scan.next());
}

Pass date string like

2021-02-23

Smile
  • 3,832
  • 3
  • 25
  • 39
1

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());
    }
}
Abra
  • 19,142
  • 7
  • 29
  • 41
  • Abra, thank you so much! I see my mistake now, in my head it made sense to jump around between LocalDate and String which is..not very smart. So thank you for this correction! and for the parsing/formatting! :) Regarding the Scanner declaration: will keep that in mind as well! I read that I should open+close scanners where I'm actually using them, maybe I misunderstood that. But yeah, thanks again for the help! – nasrot Feb 23 '21 at 12:26