views:

631

answers:

3

Is there a good, strict date parser for Java? I have access to Joda-Time but I have yet to see this option. I found the "Is there a good date parser for Java" question, and while this is related it is sort of the opposite. Whereas that question was asking for a lenient, more fuzzy-logic and prone to human error parser, I would like a strict parser. For example, with both JodaTime (as far as I can tell) and simpleDateFormat, if you have a format "MM/dd/yyyy":

parse this: 40/40/4353

This becomes a valid date. I want a parser that knows that 40 is an invalid month and date. Surely some implementation of this exists in Java?

+11  A: 

I don't see that Joda recognizes that as a valid date. Example:

strict = org.joda.time.format.DateTimeFormat.forPattern("MM/dd/yyyy")
try {
    strict.parseDateTime('40/40/4353')
    assert false
} catch (org.joda.time.IllegalFieldValueException e) {
    assert 'Cannot parse "40/40/4353": Value 40 for monthOfYear must be in the range [1,12]' == e.message
}



As best as I can tell, neither does DateFormat with setLenient(false). Example:

try {
    df = new java.text.SimpleDateFormat('MM/dd/yyyy')
    df.setLenient(false)
    df.parse('40/40/4353')
    assert false
} catch (java.text.ParseException e) {
    assert e.message =~ 'Unparseable'
}

Hope this helps!

yawmark
Which version of JodaTime are you using?
MetroidFan2002
1.6 certainly exhibits this behaviour.
Jon Skeet
That's really odd. I had a test that was failing, but for some reason it works now and I get that exception you mentioned. Very strange. Joda time it is, then! :)
MetroidFan2002
I'm using Joda 1.5.2.
yawmark
@yawmark. I think you drop some Perl code there "=~"
OscarRyz
That's good to know about DateFormat (there's so much there it's hard to find the particular method you're looking for), but I like JodaTime because it doesn't have any synchronization issues with a formatter instance. It's a real gotcha with DateFormat.
MetroidFan2002
@Oscar: It's Groovy. :o)http://groovy.codehaus.org/
yawmark
A: 

my anwers are 8 ,16 and 28

A: 

A good way to do strict validation with DateFormat is re-formatting the parsed date and checking equality to the original string:

String myDateString = "87/88/9999";
Date myDate = dateFormat.parse(myDateString);
if (!myDateString.equals(df.format(myDate))){
  throw new ParseException();
}

Works like a charm.

Rolf