0

Why is ParseException not caught here? When I enter a date consisting of more than 4 digits it just accepts it, but it shouldn't as I set lenient to false. When I enter letters for the year I get parse exception, but it's not caught.

Example session with too many digits in the year:

Enter name:
Ievgeniia Leleka
Enter position:
Programmer
Enter year
20023
Worker{name='Ievgeniia Leleka', position='Programmer', year='20023'}

Example with letters for year:

Enter name:
Ievgeniia Leleka
Enter position:
Programmer
Enter year
abc
java.text.ParseException: Unparseable date: "abc"
    at java.base/java.text.DateFormat.parse(DateFormat.java:399)
    at Main.isThisDateValid(Test.java:12)
    at Main.main(Test.java:39)
Worker{name='Ievgeniia Leleka', position='Programmer', year='abc'}
public class Main {

    public static boolean isThisDateValid(String dateToValidate, String dateFormat) {
        if (dateToValidate == null) {
            return false;
        }

        SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
        sdf.setLenient(false);

        try {
            Date date = sdf.parse(dateToValidate);
        }
        catch (ParseException exc) {
            exc.printStackTrace();
            return false;
        }

        return true;
    }

   
  • Aside: why an array with a single element? – Chris May 24 '23 at 04:20
  • It looks like `SimpleDateFormat` will use leniency to constrain the hour from 1 to 12, or 1 to 24. It doesn't appear that it evaluates the year value. – Reilas May 24 '23 at 04:32
  • Does this answer your question? [SimpleDateFormat parse(string str) doesn't throw an exception when str = 2011/12/12aaaaaaaaa?](https://stackoverflow.com/questions/8428313/simpledateformat-parsestring-str-doesnt-throw-an-exception-when-str-2011-12) – geocodezip May 24 '23 at 04:44
  • 2
    Use only the modern *java.time* classes, never `Date`, `Calendar`, `SimpleDateFormat`, etc. Example: `java.time.Year.parse ( input , DateTimeFormatter.ofPattern ( "uuuu" ) )` – Basil Bourque May 24 '23 at 04:52
  • Yes, this is just one little example of how confusing `SimpleDateFormat` is. I strongly recommend that you don’t use that class nor `Date`, which was also poorly designed. Both are fortunately long outdated. Use `Year` and `DateTimeFormatter` from [java.time, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/index.html). – Ole V.V. May 24 '23 at 05:36
  • 1
    Does this answer your question? [SimpleDateFormat is accepting date format which is not mentioned](https://stackoverflow.com/questions/71597191/simpledateformat-is-accepting-date-format-which-is-not-mentioned). Also perhaps [this](https://stackoverflow.com/questions/63526858/java-data-format-is-not-working-in-all-scenarios) and [this](https://stackoverflow.com/questions/73985417/date-format-issue-dd-mm-yyyy). – Ole V.V. May 24 '23 at 06:36
  • Ievgeniia Leleka, welcome to Stack Overflow. It seems that for your next questions it will be a good idea to train creating a [mre] since questions with more code than needed tend to be closed. Only this time I added one for you (considering deleting your original code completely from the question -- you can do that yourself if you agree). Consider it an exception. – Ole V.V. May 24 '23 at 08:45
  • 1
    FWIW - https://stackoverflow.com/questions/73985417/date-format-issue-dd-mm-yyyy is the closest of the dups that you found to this Q. (See my comment below.) Unfortunately, the number of question downvotes makes it a poor dup target. – Stephen C May 24 '23 at 09:04
  • *When I enter letters for the year I get parse exception, but it's not caught.* This sounds weird indeed. How do you determine that you get an exception, and how do you determine that it is not caught? Is your program crashing with a stack trace? You may want to include that stack trace in your question (format as code to preserve lines and formatting). – Ole V.V. May 24 '23 at 09:30
  • 1
    Trying to run your code I think that your immediate problem lies in this line: `isThisDateValid(year, "yyyy");`. You are not picking up the return value (false or true) from the call to `isThisDateValid()`. No matter if the method says the date is valid or not, your program just goes on to create a new `Worker` with the year string that the user entered, valid or not. So yes, you can have a `Worker` where the year consists of letters if that’s what the user entered. You probably want some `if` statement there? – Ole V.V. May 24 '23 at 14:59
  • Meaning that your exception *is being* caught. The stacktrace that you see comes from `exc.printStackTrace();` in your `catch` clause. If I interpret the situation correctly. – Ole V.V. May 25 '23 at 06:55
  • 1
    Thanks a lot for the comments! Used DateTimeFormatter and DateTimeParseException and it now catches both letters and too many digits. – Ievgeniia Leleka May 28 '23 at 01:58
  • Good to read that you got it solved. Maybe you want to post an answer to your own question? – Ole V.V. May 30 '23 at 04:35

1 Answers1

0

See the documentation of SimpleDateFormat.parse(): https://docs.oracle.com/javase/8/docs/api/java/text/DateFormat.html#parse-java.lang.String-

The key part being: Parses text from the beginning of the given string to produce a date. The method may not use the entire text of the given string.

So if you input "1990a" it will not generate a ParseException because 1990 is a valid value for "yyyy".

But if you input "a1990" it will throw ParseException.

You should include your input and output in the question.

A related question shows how you can be sure it is using the whole string: Force SimpleDateFormat to parse the whole string

KC Wong
  • 2,410
  • 1
  • 18
  • 26
  • Actually, the real explanation is in the javadoc: *"Year: For parsing, if the number of pattern letters is more than 2, the year is interpreted literally, regardless of the number of digits."*. And as you can see from the OP's example, there are 5 digits in the date's year *when it is unparsed*. – Stephen C May 24 '23 at 09:00
  • @StephenC The question said *date consisting of more then 4 digits*. In all fairness the 5-digit number now in the code, 20223, was my interpretation of that expression. This answerer seems to have interpreted it rather as for example `1990a`, which I don’t think was meant, but only the OP can know for sure. – Ole V.V. May 24 '23 at 09:34
  • If that is the answerer's interpretation, it is a literal misinterpretation. `a` is not a (decimal) digit and conventional date formats don't express years in hexadecimal. Now I will grant you that the OP might *also* have said digit when they meant character, but we shouldn't by trying to read the OP's mind. (Or at least, not without stating our assumptions; e.g. "I think you meant X .. and that is what I am answering." – Stephen C May 24 '23 at 11:27
  • @StephenC When I answered, the question did not have the example input and output; that's why I said "You should include your input and output in the question.". Instead OP stated "When I enter letters for the year I [should] get parse exception, but it's not caught." which I assume he was adding an alphabet to the year input. – KC Wong May 25 '23 at 01:43