Reputation: 273
Im trying to check for date validity. I can only use else and switch cases. Im not sure if the following can be simplified.
if (monthNum<1||monthNum>12){
validDate=false;
System.out.println("Invalid Date Entered");
}
else if ((monthNum==1||monthNum==3||monthNum==5||monthNum==7||monthNum==8||monthNum==10||monthNum==12)&&(dayNum<1||dayNum>31)) {
validDate=false;
System.out.println("Invalid date entered");
}
else if ((monthNum==4||monthNum==6||monthNum==9||monthNum==11)&&(dayNum<1||dayNum>30)){
validDate=false;
System.out.println("Invalid date entered");
}
else if (monthNum==2 &&(dayNum<1||dayNum>28)) {
validDate=false;
System.out.println("Invalid date entered");
}
else {
validDate=true;
}
Upvotes: 0
Views: 476
Reputation: 23373
The following is shorter, it uses the fact that you can add more detailed checks onto checks that always hold (i.e. all months have less than 32 days) and by moving the sysout message to where all tests are done.
boolean validDate = (monthNum >= 1 && monthNum <= 12 && dayNum >= 1 && dayNum <= 31);
if (monthNum == 4 || monthNum == 6 || monthNum == 9 || monthNum == 11) {
validDate &&= (dayNum <= 30);
}
else if (monthNum == 2) {
validDate &&= (dayNum <= 28);
}
if (!validDate) {
System.out.println("Invalid Date Entered");
}
In case it is permitted to use a lookup table, you can simplify further like this:
int[] monthDays = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
boolean validDate = (monthNum >= 1 && monthNum <= 12 &&
dayNum >= 1 && dayNum <= monthDays[monthNum - 1]);
if (!validDate) {
System.out.println("Invalid Date Entered");
}
Upvotes: 0
Reputation: 1381
Adding leap-year handling to the answer from mergeconflict:
private static boolean validateDate(int yearNum, int monthNum, int dayNum) {
if (monthNum < 1 || monthNum > 12) return false;
if (dayNum < 1 ) return false;
switch(monthNum) {
case 1: case 3: case 5: case 7: case 8: case 10: case 12:
return dayNum <= 31;
case 4: case 6: case 9: case 11:
return dayNum <= 30;
default: // 2
boolean leapYear = (yearNum % 4 == 0 && yearNum % 100 != 0) || yearNum % 400 == 0;
if (leapYear) {
return dayNum <= 29;
} else {
return dayNum <= 28;
}
}
}
Upvotes: 0
Reputation: 15729
First, do one check at the very beginning for a dayNum < 1. I don't know of any month with a day 0. :-)
If you keep the current if/else system, I would at least split the date check from the month check. Also, my personal preference, make the logic positive - this is usually easier to follow. And a comment or two would be nice...
e.g.
// Thirty days hath September, April, June, and November
else if ((monthNum==4||monthNum==6||monthNum==9||monthNum==11)) {
validDate = dayNum<=30; // note that logic is now "positive"
if (!validDate)
System.out.println("Invalid date entered");
}
I don't know where you are in your coursework, but have you considered using arrays? An array of 12 ints, the maximum day for each of the 12 months, would be useful.
Upvotes: 0
Reputation: 15092
1-28 is always valid. Start with that. Only do the switch if the number is > 28.
Upvotes: 0
Reputation: 19347
Here's some things that you could think about:
In well-designed software, this validation would likely appear in its own method:
bool validateDate(int monthNum, int dayNum) {
// your code goes here
}
We can also split the month and day validation into their own methods, e.g.:
bool validateMonth(int monthNum) {
return (1 <= monthNum) && (monthNum <= 12)
}
bool validateDay(int monthNum, int dayNum) {
// ...
}
For the inside of the validateDay
method, any day less than 1 is bad, so we can pull that out front:
if (day < 1)
return false;
The I would definitely use a switch for the rest:
switch(monthNum) {
case 1:
case 3:
// ...
case 12:
return dayNum <= 31;
// similarly for the other months
// ...
case default:
// should probably do something about invalid monthNum
}
The two method are easily combined by
bool validateDate(int monthNum, int dayNum) {
return validateMonth(monthNum) && validateDay(dayNum);
}
This isn't a drastic change to your code (it has almost the same flow), but it's more organized, and a switch
handles multiples ==
checks much more conveniently.
Upvotes: 1
Reputation: 8276
boolean validateDate(int monthNum, int dayNum) {
if (dayNum < 1)
return false;
switch (monthNum) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
return dayNum <= 31;
case 4:
case 6:
case 9:
case 11:
return dayNum <= 30;
case 2:
return dayNum <= 28;
}
return false;
}
Upvotes: 0
Reputation: 5032
(simplified conditions for brevity)
if (a){
validDate=false;
System.out.println("Invalid Date Entered");
}
else if (b) {
validDate=false;
System.out.println("Invalid date entered");
}
else if (c){
validDate=false;
System.out.println("Invalid date entered");
}
else if (d) {
validDate=false;
System.out.println("Invalid date entered");
}
else {
validDate=true;
}
can be changed to:
boolean validDate = !(a||b||c||d);
does this help?
Upvotes: 2
Reputation: 2630
Instead of writing your own date-checking logic, I suggest looking at java.util.Calendar and using setLenient(false).
Check the JavaDocs at http://docs.oracle.com/javase/6/docs/api/java/util/Calendar.html#setLenient(boolean)
Upvotes: 0