3

I am expecting an exception to be thrown for following code and input:

SimpleDateFormat getDateTimeFormat(String requiredFormat)
{
    SimpleDateFormat dateTimeFormat = new SimpleDateFormat(requiredFormat);
    //this will make sure that if parsing fails exception is thrown
    dateTimeFormat.setLenient(false);
    return dateTimeFormat;
}
Date date = getDateTimeFormat("MM/dd/yyyy HH:mm").parse(estimatedDeliveryDttm);

Input: 10/25/16 17:46

I am expecting a parsing exception since year is not given as 'yyyy', but I am getting year as '0016' which I do not want. I cann't use JAVA 8. I already tried JAVA 7 (including parsing position approach) and JODA Date Time API.

Ajay Sharma
  • 846
  • 10
  • 21
  • @nbrooks Yes I want exception to be thrown so that I can show error to my user. FYI I also tried parsing position approach as well – Ajay Sharma Oct 13 '16 at 07:29
  • Duplicate. Already discussed here: http://stackoverflow.com/questions/33082641/java-date-validation-joda-time – Azathoth Oct 13 '16 at 07:36
  • @Azathoth Thanks for your time, but that question is little peculiar as compared to the one mentioned by you. Here I am asking why it is not throwing exception despite passing only 2 digits for year. – Ajay Sharma Oct 13 '16 at 10:24

1 Answers1

2

From the Javadocs of SimpleDateFormat

Year: If the formatter's Calendar is the Gregorian calendar, the following rules are applied.

For formatting, if the number of pattern letters is 2, the year is truncated to 2 digits; otherwise it is interpreted as a number.

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.

For parsing with the abbreviated year pattern ("y" or "yy"),SimpleDateFormat must interpret the abbreviated year relative to some century. It does this by adjusting dates to be within 80 years before and 20 years after the time the SimpleDateFormat instance is created. For example, using a pattern of "MM/dd/yy" and a SimpleDateFormat instance created on Jan 1, 1997, the string "01/11/12" would be interpreted as Jan 11, 2012 while the string "05/04/64" would be interpreted as May 4, 1964. During parsing, only strings consisting of exactly two digits, as defined by Character.isDigit(char), will be parsed into the default century. Any other numeric string, such as a one digit string, a three or more digit string, or a two digit string that isn't all digits (for example, "-1"), is interpreted literally. So "01/02/3" or "01/02/003" are parsed, using the same pattern, as Jan 2, 3 AD. Likewise, "01/02/-3" is parsed as Jan 2, 4 BC.

See the bold point above which explains the behavior you are seeing.

Community
  • 1
  • 1
Sanjeev
  • 9,876
  • 2
  • 22
  • 33
  • Thanks for explanation. Could you please suggest a way by which we can enforce this without using JAVA 8 – Ajay Sharma Oct 14 '16 at 05:08
  • I do not think that it will be possible using Standard Date-Time API prior to java 8. One way you can enforce this by putting a custom logic, If you know the format then you can use regex to match your incoming date against the format. And if that is not matched then throw an exception – Sanjeev Oct 14 '16 at 06:35