1

I want to validate the date in the format yyyy-MM-dd. If i give two digits for year (ie YY instead of YYYY) it is not throwing any exception and 00 is getting appended to the date time format on parsing the date.

I have added setLenient(false);, but still it is not validating correctly.

Can anyone please help me on this?

DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy");
formatter.setLenient(false);
try {
   Date date = (Date)formatter.parse("15-05-30"); //In this line year is getting appened with 00 and becomes 0015
   reciptDate = dateFormat.format(date);
} catch (ParseException pe) {
   return false;
}
Rozart
  • 1,668
  • 14
  • 27
kana
  • 43
  • 1
  • 6
  • And why don't you simply parse `"2015-05-30"`? Is there any reason why you want another `SimpleDateFormat` than the one you actually need? – LordAnomander Jan 15 '16 at 12:20
  • 1
    We want to throw some exception in case if the format does not match with yyyy-MM-dd – kana Jan 15 '16 at 12:22
  • http://stackoverflow.com/questions/18534343/why-simpledateformatmm-dd-yyyy-parses-date-to-10-20-20128 See this link. You should probably define an additional check if the year is smaller than let's say 2000. Other than that 15 is a valid number for a year. – LordAnomander Jan 15 '16 at 12:26
  • For example: `if (date.before(new Date(0L))) return false;` – LordAnomander Jan 15 '16 at 12:28

2 Answers2

2

The API docs for SimpleDateFormat specifies, for Year:

For parsing, if the number of pattern letters is more than 2, the year is interpreted literally, regardless of the number of digits. So using the pattern "MM/dd/yyyy", "01/11/12" parses to Jan 11, 12 A.D.

So, you can't use SimpleDateFormat as-is, to perform the validation you want (note that 1, 2 or 3 digit years are valid years, and so is > 4 digit years, but I assume this to be out of scope for the question).

Validating that you have exactly 4 digits year should be trivial to do it with a regular expression.

For example:

Pattern pattern = Pattern.compile("[0-9]{4}-[0-9]{2}-[0-9]{2}");

System.out.println("15-05-30: " + pattern.matcher("15-05-30").matches());
System.out.println("2015-05-30: " + pattern.matcher("2015-05-30").matches());
System.out.println("0015-05-30: " + pattern.matcher("0015-05-30").matches());

Outputs:

15-05-30: false
2015-05-30: true
0015-05-30: true
Harald K
  • 26,314
  • 7
  • 65
  • 111
2

If you are working on Java-8 you can specify the minimum width of year component.

DateTimeFormatter fmt = new DateTimeFormatterBuilder()
    .appendValue(ChronoField.YEAR, 4, 4, SignStyle.NEVER)
    .appendPattern("-MM-dd")
    .toFormatter();
LocalDate date = LocalDate.parse("15-05-30", fmt);

The error message is:

Exception in thread "main" java.time.format.DateTimeParseException:

Text '15-05-30' could not be parsed at index 0

at java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1949)

at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1851)

at java.time.LocalDate.parse(LocalDate.java:400)

Meno Hochschild
  • 42,708
  • 7
  • 104
  • 126