Validating dates is more complex than checking each parameter. For example, calling it with (29, 2, 2000)
would be invalid (recall that 2000 was not a leap year), even though all parameters are "within range".
The only sane way to check is to attempt to parse a Date from the parameters and catch the exception. There are a couple of ways to do this, but the simplest is this:
public Rehearsal(int d, int m, int y) {
try {
sdf = new SimpleDateFormat("d-M-yyyy");
sdf.setLenient(false);
sdf.parse(d + "-" + m + "-" + y);
} catch (ParseException e) {
// the parameters are not valid
}
// rest of code
}
Note the call to setLenient()
, which is required, otherwise invalid input "rolls over" to the next available valid date - for example 36-12-2012
would be parsed as 05-01-2013
.
The best place to put this code would be in the constructor, throwing an exception:
public Rehearsal(int d, int m, int y) {
try {
sdf = new SimpleDateFormat("d-M-yyyy");
sdf.setLenient(false);
sdf.parse(d + "-" + m + "-" + y);
} catch (ParseException e) {
// the parameters are not valid
throw new IllegalArgumentException();
}
day = d;
month = m;
year = y;
}
And you would catch this wherever it is called.
Rehearsal newrehearsal;
try {
newrehearsal = new Rehearsal(1, 2, 3);
} catch (IllegalArgumentException ex) {
JOptionPane.showMessageDialog(null, "Invalid date input!", "Error", JOptionPane.WARNING_MESSAGE);
return;
}
// rest of method
An even better design would be to pass a Date object, putting the onus on the caller to validate input, and there would be less throw and catch code.