Issue Details (XML | Word | Printable)

Key: VALIDATOR-221
Type: Bug Bug
Status: Closed Closed
Resolution: Won't Fix
Priority: Minor Minor
Assignee: Unassigned
Reporter: Carsten Drossel
Votes: 0
Watchers: 1
Operations

If you were logged in you would be able to see more operations.
Commons Validator

DateValidator considers "02/29" with format "MM/dd" invalid

Created: 29/Jan/07 01:37 PM   Updated: 12/Nov/07 07:25 PM
Return to search
Component/s: None
Affects Version/s: 1.3.1 Release
Fix Version/s: None

Time Tracking:
Not Specified

Environment: Windows XP, Java 1.5.0_04

Resolution Date: 12/Nov/07 07:04 PM


 Description  « Hide
When the date pattern contains only day and month the isValid(..)-method of DateValidator returns false for the value Feb. 29th.

Here is a JUnit test that fails:
public void testFebruary29th() throws Exception {
assertTrue( DateValidator.getInstance().isValid( "02/29", "MM/dd", true ) );
}

The DateValidator uses the parse(..)-method of SimpleDateFormat for the validation. This method appears to complete any date using 01/01/1970 00:00. Since 1970 was not a leap year a ParseException is thrown for the input "02/29" with the format "MM/dd" because 02/29/1970 is not a valid date.

But IMHO "02/29" should be valid. An example where it makes sense is a search for persons with a certain birthday.



 All   Comments   Work Log   Change History   Subversion Commits      Sort Order: Ascending order - Click to sort in descending order
Niall Pemberton added a comment - 29/Jan/07 10:46 PM
This is a valid point but DateValidator is built on the premise of validating dates using java's DateFormat's parse method. Since as you point out this is a defect in the DateFormat implementation(s) then I don't really see a solution to this issue for the implementations validator provides.

If you can put forward a solution, I'd be happy to consider it - if not though I'll probably close this as WONT FIX.


Carsten Drossel added a comment - 30/Jan/07 07:39 AM
I have a work-around (but I'm not very proud of it). When the date pattern contains day and month only I add a leap year to the value. Like this:

if ( datePattern.contains( "d" ) && datePattern.contains( "M" ) && !datePattern.contains( y ) ) {
datePattern += "/yyyy";
value += "/2004";
}
... = GenericValidator.isDate( value, datePattern, true )

I don't think it's a defect in the implementation of the parse method of DateFormat. Which Date should be returned for "02/29"? 03/01/1970 00:00? 02/29/1972 00:00? It's just bad luck that the year zero 1970 was not a leap year.


Henri Yandell added a comment - 30/Jan/07 05:13 PM
The Date that should be returned is 02/29/2007 as that's the current year - which is invalid.

Next year 02/29 will be valid [no idea DateFormat wise, but that's what I'd expect :) ]


Gabriel Belingueres added a comment - 30/Jan/07 08:20 PM
I think there is a subtle mistake here in trying to use a DateValidator to validate if "02/29" is a valid date. The thing is that February the 29 is valid depending on the year you are talking about, and this is a necessary context information that is lacking here.

As of why SimpleDateFormat assumes by default that you are talking about 1970 instead of throwing an exception is beyond me understanding.

See this other example:

df = new SimpleDateFormat("dd");
df.setLenient(false);
d = df.parse("31");

Now d is 01/31/1970, so it is valid. Again SimpleDateFormat assumes month 1, year 1970.

Now I think that you should better of relaying in a regexp validator or some custom functionality since what you are trying to validate definitively is not a date.

Perhaps DateValidator could detect those incomplete cases. May be it could check the pattern parameter and try to ask if it include the following sub strings: d or dd or ddd, M or MM or MMM, yy or yyyy to detect those invalid cases?

Anyway, as long as DateValidator is relying on SimpleDateFormat I see no simple solution here.


Carsten Drossel added a comment - 31/Jan/07 04:04 PM
According to the Javadoc ("Checks if the field is a valid date.", "true if the value can be converted to a Date.") I guess I'm using the method in an inappropriate way by using a date format for a 'partial date' that does not include a year. In this case I agree that this issue is not a bug.

If DateValidator can be used for partial dates however, "02/29" should be valid regardless of the year. It makes sense to search for people born on a February 29th. February 29th exists while February 30th doesn't.


Niall Pemberton added a comment - 01/Feb/07 07:48 AM
I don't disagree with any of the comments here - Gabriel makes a good point that using an alternative such as regexp would be another way to implement a date validator - and I agree with Carsten that it should work and understand his frustration that it doesn't. Given that its built to depend on java DateFormat's parse unfortunately its limited by the weakness of its implementation and Calendar. If there was a reasonable fix I would apply it - but I'd rather avoid nasty hacks to solve this issue - since I think going down that route would be never ending given the weaknesses of java's data handling. In defence of using DateFormat to validate it seems to make sense to use the same mechanism that people generally use to format a date as a String to subsequently parse and validate. Another alternative would be to look at Joda Time[1] to create a data validator - although I was aiming for "dependency free" in the routines package. Out of interest the author of Joda Time (commons committer Stephen Colebourne) has just had his proposal for a date/time JSR[2] accepted (JSR 310) which is motivated out of issues with java's date handling.

[1] http://joda-time.sourceforge.net/
[2] http://jcp.org/en/jsr/detail?id=310


Henri Yandell added a comment - 15/Aug/07 05:32 AM
+1 to close this as WONTFIX.

Gabriel Belingueres added a comment - 15/Aug/07 02:19 PM
I agree on WONTFIX.

Ben Speakmon added a comment - 12/Nov/07 07:04 PM
Resolving as wontfix per comments.

Ben Speakmon made changes - 12/Nov/07 07:04 PM
Field Original Value New Value
Resolution Won't Fix [ 2 ]
Status Open [ 1 ] Resolved [ 5 ]
Henri Yandell made changes - 12/Nov/07 07:25 PM
Status Resolved [ 5 ] Closed [ 6 ]