If statement not working correctly for dates
I wrote an if
statement that should write different output depending on the data. It works if int y = 2000, m = 5, d = 06;
, however it doesn't output the correct value when int y = 2889, m = 44, d = 16;
.
This is my code. Could someone please help me to understand what is wrong.
public class Date1 {
private int year = 1; // any year
private int month = 1; // 1-12
private int day = 1; // 1-31 based on month
//method to set the year
public void setYear(int y) {
if (y <= 0) {
System.out.println("That is too early");
year = 1;
}
if (y > 2011) {
System.out.println("That year hasn't happened yet!");
y = 2011;
} else {
year = y;
}
}
public int setMonth(int theMonth) {
if ( theMonth > 0 && theMonth <= 12 ) { // validate month
return theMonth;
} else { // month is invalid
System.out.printf("Invalid month (%d) set to 1.", theMonth);
return 1; // maintain object in consistent state
} // end else
}
public int setDay( int theDay) {
int[] daysPerMonth = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
// check if day in range for month
开发者_如何学运维 if ( theDay > 0 && theDay <= daysPerMonth[ month ] ) {
return theDay;
}
// check for leap year
if ( month == 2 && theDay == 29 && ( year % 400 == 0 || ( year % 4 == 0 && year % 100 != 0 ) ) ) {
return theDay;
}
System.out.printf( "Invalid day (%d) set to 1.", theDay );
return 1; // maintain object in consistent state
}
//method to return the year
public int getYear() {
return year;
}
//method to return the month
public int getMonth(){
return month;
}
//method to return the day
public int getDay(){
return day;
}
// return a String of the form year/month/day
public String toUniversalStringTime() {
return String.format( "The date using a default constructor %d/%d/%d \n", getYear(), getMonth(), getDay() );
} // end toUniversalStringTime
}
public class Date1Test {
public static void main(String[] args) {
int y = 2000, m = 5, d = 06;
Date1 d1 = new Date1(); //create a new object
System.out.println(d1.toUniversalStringTime()); //call toUniversalStringTime()
System.out.printf("The date I created is %d/%d/%d \n", y , m , d);
}
}
I don't see anywhere in your code where you are calling the setDay, setMonth or setYear methods, so I would expect the call to toUniversalStringTime to always print
"The date using a default constructor 111 \n"
Then after that call you print it again manually using the values for y, m and d
"The date I created is 200056 \n"
You need to call the set methods on the d1 object after creation, or pass in the parameters to a constructor to set them, e.g.
d1.setYear(y);
d1.setMonth(m);
d1.setDay(d);
but please pay attention to some of the other comments that have been made with regards to refactoring your code, because as has been mentioned, each of your setter methods have fundamental flaws in them that need to be fixed first.
Other general notes to your code:
In your setYear method you are using the value of y to update the year variable of the object, but in the second if:
if (y > 2011) {
System.out.println("That year hasn't happened yet!");
y = 2011;
}
you are actually setting y
to 2011 rather than year
, so this will have no effect.
For some reason in your setMonth method you are not actually setting the month, but you are just validating the value that is passed in, i.e. if the value is not between 1 and 12 you return 1. So the code doesn't match the name of the method and you should change one or the other.
Your setDay method is the same as setMonth in that it doesn't actually set the day, just validates it. But what's even worse here is that the call to setDay depends heavily on the month and year already having been set, since you use the month
and year
variables to determine whether or not the day is valid. This means that setDay must only be called after setMonth and setYear, otherwise you will always default to checking against January 0001 (since month and year are set to 1 by default).
Your year setter is wrong:
//method to set the year
public void setYear(int y){
if (y <= 0)
{
System.out.println("That is too early");
year = 1;
}
if (y > 2011)
{
System.out.println("That year hasn't happened yet!");
y = 2011;
}
else //<-- problem, makes the next stamtement only be executed if y <= 2011
year = y;
}
I guess the last else
statement is your problem, it makes that the year is only updated if it is before 2011. But I guess because of the statement y = 2011
it should be limited to 2011 -- so what you need is to remove the else
or write it in a simple way:
public void setYear(int year) {
this.year = Math.max(1,Math.min(2011,year));
}
Your setter methods should actually set a field and return nothing (void). setYear is OK, but Two of your setter methods, setMonth and setDay, don't set any class fields and return a value, an int, which makes no sense. The question for you is, which field should setMonth change, and which field should setDay change? Once you answer this question, you can alter your methods so that they'll work better. Please comment if any of this doesn't make any sense.
E.G. your setter is like so:
// assuming you have an int field foo that should be > 0 and <= 100
public int setFoo(int foo) {
if (foo < 0) {
return 0;
} else if (foo > 100) {
return 100;
} else {
return foo;
}
}
When it should instead be more like:
public void setFoo(int foo) {
if (foo < 0) {
this.foo = 0;
} else if (foo > 100) {
this.foo = 100;
} else {
this.foo = foo;
}
}
See the difference?
精彩评论