Validation whether a string can be parsed to a valid date according to a supplied formatting string (which should conform to the formatting rules as supplied in DateFormat).
This version can also flag dates in the past as error (we need that because many of our applications should accept only dates in the future, for example delivery dates).

To be nice it also checks for illegal input that would parse into a valid (but possibly unintended) date value, for example 35-24-2004 is not accepted even if DateFormat.parse() allows it (simply rolling forward to the next real date).

Tested using J2SDK 1.4.2 and 1.5.0

	/**
	 * Validate whether the argument string can be parsed into a 
	 * legal date.<br />
	 * 
	 * Does check for formating errors and illegal data (so an invalid
	 * month or day number is detected).
	 * @param allowPast set to true to allow dates in the past, false if
	 * only dates in the future should be allowed.
	 * @param formatStr date format string to be used to validate against
	 * @return true if a correct date and conforms to the restrictions
	 */
	public static boolean validateDate(String dateStr, 
										boolean allowPast, 
										String formatStr)
	{
                         if (formatStr == null) return false; // or throw some kinda exception, possibly a InvalidArgumentException
		SimpleDateFormat df = new SimpleDateFormat(formatStr);
		Date testDate = null;
		try
		{
			testDate = df.parse(dateStr);
		}
		catch (ParseException e)
		{
			// invalid date format
			return false;
		}
		if (!allowPast)
		{
			// initialise the calendar to midnight to prevent 
			// the current day from being rejected
			Calendar cal = Calendar.getInstance();
			cal.set(Calendar.HOUR_OF_DAY, 0);
			cal.set(Calendar.MINUTE, 0);
			cal.set(Calendar.SECOND, 0);
			cal.set(Calendar.MILLISECOND, 0);
			if (cal.getTime().after(testDate)) return false;
		}
		// now test for legal values of parameters
		if (!df.format(testDate).equals(dateStr)) return false;
		return true;
	}

But here when we pass dateStr as YYYY/MM/DD for that 2010/02/31 passes, but feb doesnt have 31st, but still this code passes :(

You get a strange behaviour because you have used a wrong syntax for the format.
You should call the method as follows:

boolean res = validateDate("2010/02/31", true, "yyyy/MM/dd");

The format is case sensitive: yyyy/MM/dd.
If you call it this way it works perfectly.

Actually I believe that you need to call the setLenient method of the SimpleDateFormat class. Check the API. I think that is something that needs to be added to the code.

The article starter has earned a lot of community kudos, and such articles offer a bounty for quality replies.