Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java DateFormat.parse thinks "100 112TH AVE NE" is a date

I'm using the code included here to determine whether given values are valid dates. Under one specific case, it's evaluating the following street address:

100 112TH AVE NE

Obviously not a date, but Java interprets it as:

Sun Jan 12 00:00:00 EST 100

The code in question:

String DATE_FORMAT = "yyyyMMdd";
try {
    DateFormat dfyyyyMMdd = new SimpleDateFormat(DATE_FORMAT);
    dfyyyyMMdd.setLenient(false);
    Date formattedDate;
    formattedDate = dfyyyyMMdd.parse(aValue);
    console.debug(String.format("%s = %s","formattedDate",formattedDate));
} catch (ParseException e) {
    // Not a date
}

The console returns:

11:41:40.063 DEBUG TestValues | formattedDate = Sun Jan 12 00:00:00 EST 100

Any idea what's going on here?

like image 485
bobanahalf Avatar asked Apr 15 '14 17:04

bobanahalf


2 Answers

The parse method does not verify that the entire string was consumed when parsing; you can have random garbage after a valid date and everything works. In this case, it's a little surprising that 100 112 can be successfully parsed as a date, but it can.

You can supply a ParsePosition to verify that the entire string was consumed when parsing.

ParsePosition pos = new ParsePosition(0);
dfyyyyMMdd.parse(aValue, pos);
if (pos.getIndex() != aValue.length()) {
    // there's garbage at the end
}
like image 141
Joni Avatar answered Nov 11 '22 20:11

Joni


As per the documentation, the parse method may NOT use the entire text of the string -

   public Date parse(String source)
               throws ParseException

    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. 

I checked the source code for SimpleDateFormat and found that it is parsing the string only up to the length of the compiledPattern.

Thus, the strings of the form -

yyyyMMdd(followed by anything)

will be parsed without any errors.

So, for e.g. it also parses -

"10000514blabla" --> Tue May 14 00:00:00 EST 1000
"100 112"        --> Sun Jan 12 00:00:00 EST 100
"1 112xyz"       --> Wed Jan 12 00:00:00 EST 1
like image 33
Wes Avatar answered Nov 11 '22 20:11

Wes