-1

I need convert a String to Date with exact format ( dd/MM/yyyy) I wrote this method :

public static Date toDate(String input, String format) throws DateConverterException {
        if (StringUtils.isEmpty(input) || StringUtils.isEmpty(format)) {
            throw new DateConverterException (String.format("Input %s or format %s is empty or", input, format));
        }
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        sdf.setLenient(false);
        Date date = null;
        try {
            date = sdf.parse(input);
        } catch (ParseException e) {
            throw new DateConverterException (e);
        }
        return date;
    }

So if input date is "06/10/" , exception is thrown = good but if input date is "06/10/1" date is constructed despite the format is not respected

Any help would be appreciated Thank you very much

ulquiorra
  • 931
  • 4
  • 19
  • 39
  • 2
    Can't reproduce. When I tested, this was thrown: "java.text.ParseException: Unparseable date: "06/10/0"" – Tunaki Oct 06 '15 at 14:24
  • @Tunaki Really ? I don't understand man , when i test with the parameters : "06/10/2" ,"dd/MM/yyyy" , the date is still constructed despite it should not – ulquiorra Oct 06 '15 at 14:30
  • @azurefrog Yeah my bad sorry , i took 0 as an example but exception is thrown indeed .try now with 06/10/1 or 06/10/2 and it will construct Date. thank you – ulquiorra Oct 06 '15 at 14:35
  • 2
    A little digging shows that SimpleDateFormat is bad at strict date parsing. [This answer](http://stackoverflow.com/a/2356590/1361506) advocates post-parse double checking, and [this answer](http://stackoverflow.com/a/19503019/1361506) has a way to extend the class to force strict parsing. – azurefrog Oct 06 '15 at 14:38
  • Possible duplicate of [SimpleDateFormat.parse() ignores the number of characters in pattern](http://stackoverflow.com/questions/16014488/simpledateformat-parse-ignores-the-number-of-characters-in-pattern) – azurefrog Oct 06 '15 at 14:39
  • @azurefrog Thank you very much . I thought i could do strict parsing with SimpleDateFormat but if lenient is buggy i will rather opt for T.J. Crowder solution and do another parsing on the year. Sorry for the inconvenience about the example with 0 as a year – ulquiorra Oct 06 '15 at 14:51
  • @user902509 The old java.util.Date and java.text.SimpleDateFormat have been supplanted by the new java.time framework ([Tutorial](http://docs.oracle.com/javase/tutorial/datetime/TOC.html)) built into Java 8 and later. A vast improvement. – Basil Bourque Oct 06 '15 at 17:06

1 Answers1

3

Yeah my bad sorry , i took 0 as an example but exception is thrown indeed .try now with 06/10/1 or 06/10/2 and it will construct Date.

From the documentation:

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

....

  • 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.

(my emphasis)

E.g., 1 is a valid year. If you want to accept years only within a certain range (say, 1800-2100), you'll need to check the year on the date after parsing it.

Community
  • 1
  • 1
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • 1
    Thank you very much man . So it's a normal behavior of SimpleDateFormat after all. I will follow your suggestion and verify the range year in addition of parsing – ulquiorra Oct 06 '15 at 14:53