-2

I am trying to implement a method which parses String to Date, and I would like to use SimpleDateFormat because that seems to do the work:

java.util.Date parseMonth(String str) throws ParseException {
    SimpleDateFormat format=new SimpleDateFormat("MM/yyyy");
    return format.parse(str);
}

But for some reasons, I get no ParseException on inputs where I expect to get one.

  • "00/2000" -> 1999-12-01, no Exception
  • "13/2000" -> 2001-01-01, no Exception

What is the preferred way to check if a String is a correct date (in respect to some implementation depended format)?

diston
  • 129
  • 3
Frank Endriss
  • 120
  • 3
  • 10
  • This question has already been answered here: https://stackoverflow.com/questions/20231539/java-check-the-date-format-of-current-string-is-according-to-required-format-or – Alexander Aurand Mar 13 '18 at 12:57
  • Everybody has their own way I prefer regex validator. – Roman C Mar 13 '18 at 12:58
  • 1
    I recommend you avoid `SimpleDateFormat`. It is not only long outdated, it is also notoriously troublesome. Instead use [java.time, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/). It is so much nicer to work with. Look into its `YearMonth` and `DateTimeFormatter` classes. – Ole V.V. Mar 13 '18 at 21:19
  • Duplicate of: [*How to parse date with only month and year*](https://stackoverflow.com/q/46780340/642706). See [correct Answer](https://stackoverflow.com/a/46780431/642706) by Andreas using the [`YearMonth`](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/YearMonth.html) class. – Basil Bourque May 14 '19 at 00:27

1 Answers1

3

SimpleDateFormat is lenient by default, so it tries to be smart (usually failing) and doing things like "month zero becomes December of previous year".

To make invalid inputs throw an exception, just disable the lenient behaviour:

SimpleDateFormat format = new SimpleDateFormat("MM/yyyy");
format.setLenient(false); // not lenient

This will throw a ParseException for invalid inputs, such as 00/2000 and 13/2000.


But now we have better API's for that. Since Java 8, there's a new date/time API, and for versions <= 7 there's a nice backport. In this API, the formatters are not lenient by default:

DateTimeFormatter fmt = DateTimeFormatter.ofPattern("MM/yyyy");
YearMonth.parse("00/2000", fmt); // exception
diston
  • 129
  • 3
  • 1
    Why the downvote? Doesn't `setLenient` solve the problem? – diston Mar 13 '18 at 16:29
  • I don’t know if that’s the case here. but some users like to downvote answers to downvoted and/or duplicate questions in order to avoid too many such questions. This is a good answer. One might still argue that it’s better to keep the answers where the original question is. – Ole V.V. Mar 13 '18 at 21:24