I'm looking to increase the conciseness of this code. I realize that I can use Joda (or Java 8's new date API), but if I were to keep this to just Java 7, any suggestions? (I care less about whitespace and formatting.)
/**
* Tests whether the date input represents
* a real date in mm/dd/YYYY format that is after the current date.
* Useful for testing send dates and expiration dates.
*
* Tests against current date minus 24 hours
* so users in different time zones from the server can
* be accommodated.
*
* @param pDateString date to be tested
* @return true if date (@12:01 am) >= yesterday (@12:02am)
*/
public static boolean isValidFutureDate(String pDateString) {
if (!isValidDate(pDateString)) {
return false;
}
StringTokenizer st = new StringTokenizer(pDateString.trim(), "/");
if (st.countTokens() != 3) {
throw new NumberFormatException("Date format should be MM/DD/YYYY.");
}
String month = st.nextToken();
String day = st.nextToken();
String year = st.nextToken();
long oneDayInMillis = 86400000;
// set reference point to yesterday's date, 12:01am
GregorianCalendar ref = new GregorianCalendar();
ref.setTime(new Date(System.currentTimeMillis() - oneDayInMillis));
ref.set(Calendar.HOUR_OF_DAY, 0);
ref.set(Calendar.MINUTE, 1);
ref.set(Calendar.AM_PM, Calendar.AM);
// set comparison time to entered day, 12:02am
GregorianCalendar now = toDate(year, month, day);
now.set(Calendar.HOUR_OF_DAY, 0);
now.set(Calendar.MINUTE, 2);
ref.set(Calendar.AM_PM, Calendar.AM);
return now.after(ref);
}
/**
* This method tests whether the date string passed in represents
* a real date in mm/dd/YYYY format.
*
* @param pDateString date to be tested
* @return a <code>boolean</code> value
*/
public static boolean isValidDate(String pDateString) {
StringTokenizer st= new StringTokenizer(pDateString.trim(), "/");
if (st.countTokens() != 3) {
throw new NumberFormatException("Date format should be MM/DD/YYYY.");
}
String month = st.nextToken();
String day = st.nextToken();
String year = st.nextToken();
return toDate(year, month, day) != null;
}
/**
* Converts a String set of date values to a GregorianCalendar object.
*
* @param year a <code>String</code> value
* @param month a <code>String</code> value
* @param day a <code>String</code> value
* @return a <code>GregorianCalendar</code> value
*/
public static GregorianCalendar toDate(final String year,
final String month,
final String day) {
int mm, dd, yyyy;
try {
if(year.length() != 4) {
throw new NumberFormatException("Please provide four(4) digits for the year.");
}
yyyy = Integer.parseInt(year);
if(yyyy == 0) {
throw new NumberFormatException("zero is an invalid year.");
}
}
catch(NumberFormatException nfe) {
throw new NumberFormatException(year + " is an invalid year.");
}
try {
mm = Integer.parseInt(month);
if(mm < 1 || mm > 12) {
throw new NumberFormatException(month + " is an invalid month.");
}
}
catch(NumberFormatException nfe) {
throw new NumberFormatException(month + " is an invalid month.");
}
try {
dd = Integer.parseInt(day);
}
catch(NumberFormatException nfe) {
throw new NumberFormatException(day + " is an invalid day.");
}
GregorianCalendar gc = new GregorianCalendar( yyyy, --mm, 1 );
if(dd > gc.getActualMaximum(GregorianCalendar.DATE)) {
throw new NumberFormatException(CalendarUtils.months[gc.get(GregorianCalendar.MONTH)] + " " + dd + " is an invalid day in "+gc.get(GregorianCalendar.YEAR) + ".");
}
if(dd < gc.getActualMinimum(GregorianCalendar.DATE)) {
throw new NumberFormatException(CalendarUtils.months[gc.get(GregorianCalendar.MONTH)] + " " + dd + " is an invalid day in "+gc.get(GregorianCalendar.YEAR) + ".");
}
return new GregorianCalendar(yyyy,mm,dd);
}