Calculate Leap Year in Java is bypassing an else statement - java

There must be a bug somewhere in my 30 lines of code but I cannot find it and it's driving me nuts.
If I execute this code using isLeapYear(2004) I receive a true:
public class LeapYear {
public static void main(String[] args) {
isLeapYear(2004);
}
public static boolean isLeapYear (int year) {
boolean status = true;
if (year >= 0 || year <= 9999) {
if (year % 4 == 0){
status = true;
System.out.println("true");
} else if (year % 100 == 0){
status = true;
System.out.println("true");
} else if (year % 400 == 0) {
status = true;
System.out.println("true");
} else {
status = false;
System.out.println("false");
}
} else if (year < 0 || year > 9999){
status = false;
System.out.println("false");
}
return status;
}
}
But if I run it for isLeapYear(-1200) it returns me a true as well but it shouldn't.
Why is my code bypassing else if (year < 0 || year > 9999) ?

you just have to change your first if statement to :
if (year >= 0 && year <= 9999) {
-1200 was always lower than 9999 so it was always going through this condition because of the ||.

Related

Trying to correctly determine whether numbers are weird

Made a program that prints if a number is weird or not. If the number is odd, it's weird. If the number is even and inclusively between 2 and 5, it is not weird. If it's even and inclusively between 6 and 20, it's weird, and if it's even and greater than 20, it's not weird. The problem I'm having here is that instead of the output displaying "This number is weird/not weird", I get "Weird" or "Not Weird" on one line, followed by "This number is 0" if it's even, or "This number is 1" if it's odd.
public Weird(int num)
{
n = num;
}
public int EvenOrOdd()
{
int check = n % 2;
int answer = n / 2;
if (check == 0 && answer >= 2 && answer <= 5)
{
System.out.println("Not Weird");
}
else if (check == 0 && answer >= 6 && answer <= 20)
{
System.out.println("Weird");
}
else if (check == 0 && answer > 20)
{
System.out.println("Not Weird");
}
else if (check != 0)
{
System.out.println("Weird");
}
return check;
}
public static void main(String[] args)
{
Weird w = new Weird(32);
Weird a = new Weird(21);
System.out.println("This number is " + w.EvenOrOdd());
System.out.println("This number is " + a.EvenOrOdd());
}
You actually return int which is value of check field. This is either 1 or 0.
When you call this line-
System.out.println("This number is " + w.EvenOrOdd());
System.out.println("This number is " + a.EvenOrOdd());
It prints either This number is 0 or This number is 1.
You can get desired output by two ways-
Way 1-
Change return type of method to void EvenOrOdd() like-
public void EvenOrOdd()
{
int check = n % 2;
int answer = n / 2;
if (check == 0 && n >= 2 && n<= 5)
{
System.out.println("Not Weird");
}
else if (check == 0 && n>= 6 && n<= 20)
{
System.out.println("Weird");
}
else if (check == 0 && n> 20)
{
System.out.println("Not Weird");
}
else if (check != 0)
{
System.out.println("Weird");
}
}
and call method in main as-
public static void main(String[] args)
{
Weird w = new Weird(32);
Weird a = new Weird(21);
w.EvenOrOdd();
a.EvenOrOdd();
}
Way 2- Change return type of method to String as-
public String EvenOrOdd()
{
int check = n % 2;
int answer = n / 2;
if (check == 0 && n>= 2 && n<= 5)
{
return "Not Weird";
}
else if (check == 0 && n>= 6 && n<= 20)
{
return "Weird";
}
else if (check == 0 && n> 20)
{
return "Not Weird";
}
else
{
return "Weird";
}
}
And main method remains same-
public static void main(String[] args)
{
Weird w = new Weird(32);
Weird a = new Weird(21);
System.out.println("This number is " + w.EvenOrOdd());
System.out.println("This number is " + a.EvenOrOdd());
}
You should return that string rather than printing it. In your function, you are returning an int but rather you should write a String. Besides that everything looks good but you can decrease the number of check like below:
public Weird(int num)
{
n = num;
}
public String EvenOrOdd()
{
int check = n % 2;
if (check == 1 || (check == 0 && n >= 6 && n <= 20)) {
return "Weird";
}else{
return "Not Weird";
}
}
public static void main(String[] args)
{
Weird w = new Weird(32);
Weird a = new Weird(21);
System.out.println("This number is " + w.EvenOrOdd());
System.out.println("This number is " + a.EvenOrOdd());
}
The value you return from a method will kind of "replace" the method call. Because you returned check:
return check;
The calls:
System.out.println("This number is " + w.EvenOrOdd());
System.out.println("This number is " + a.EvenOrOdd());
are basically:
System.out.println("This number is " + 0);
System.out.println("This number is " + 1);
You seem to be confused about returning and printing. Your method should look like this:
public String EvenOrOdd()
{
int check = n % 2;
int answer = n / 2;
if (check == 0 && n >= 2 && n <= 5)
{
return "Not Weird";
}
else if (check == 0 && n >= 6 && n <= 20)
{
return "Weird";
}
else if (check == 0 && n > 20)
{
return "Not Weird";
}
else
{
return "Weird";
}
}
Now the two calls is basically:
System.out.println("This number is " + "Weird");
System.out.println("This number is " + "Not Weird");

Why is my code skipping the 1st date for finding the next day?

I'm supposed to make code that shows the next day, and this works except for the months that end in 31. For example, when I enter 3/31/2000, it gives me 4/2/2000 and skips the first day? I'm not sure why?
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package lab53;
import java.util.Scanner;
/**
*
* #author Owner
*/
public class Lab53 {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
Scanner keyboardInput = new Scanner(System.in);
int year, month, day;
System.out.println("Enter year/month/day");
year = keyboardInput.nextInt();
month = keyboardInput.nextInt();
day = keyboardInput.nextInt();
if ((month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12))
{
day=thirtyOneDaysMonth(day);
if(day==1 && month==12){
++year;
month=1;
}
else if(day==1 && month!=12)
++month;
}
if ((month==2 || month == 4 || month == 6 || month == 9 || month == 11))
{
day=thirtyDaysMonth(day);
if(month==2 && isLeapYear(year))
{
if(day>29)
{
++month;
day=1;
}
}
else if( day>28 && month==2)
{
++month;
day=1;
}
else
{
if(day==1)
{
++month;
day=1;
}
}
}
System.out.println("The next date is:"+ month + "/" + day + "/" + year);
}
public static int thirtyOneDaysMonth(int day)
{
if(day==31)
day=1;
else
++day;
return day;
}
public static int thirtyDaysMonth(int day)
{
if(day==30)
day=1;
else
++day;
return day;
}
public static boolean isLeapYear(int year)
{
if((year % 400 == 0) || ((year % 4 == 0) && (year % 100 != 0)))
return true;
else
return false;
}
}
Change if ((month==2 || month == 4 || month == 6 || month == 9 || month == 11)) to else if ((month==2 || month == 4 || month == 6 || month == 9 || month == 11)).
On a day = 31 you're updating the month in your if statement. Then you leave the if but then enter your next if statement that handles months with 30 days. Your code then increments the day again.
Because after the first if has increased 3/31/2000 to 4/1/2000 the second if is evaluated which will again increase the day. Make the second if an else if instead.
In the case of month==3 and day==31, day is bumped back to 1 by
day=thirtyOneDaysMonth(day);
then the month is bumped up by
else if(day==1 && month!=12)
++month;
then the next if statement is true because now month == 4
if ((month==2 || month == 4 || month == 6 || month == 9 || month == 11))
connecting it to the previous if statement with an else if will fix the issue
else if ((month==2 || month == 4 || month == 6 || month == 9 || month == 11))

Repeating code for leap year

I already know how to check for a leap year, like this:
import java.util.*;
public class LeapYear {
public static void main(String[] args) {
int year;
{
Scanner scan = new Scanner(System.in);
System.out.println("Enter year: ");
year = scan.nextInt();
if ((year % 4 == 0) && year % 100 != 0) {
System.out.println(year + " is a leap year.");
} else if ((year % 4 == 0) && (year % 100 == 0)
&& (year % 400 == 0)) {
System.out.println(year + " is a leap year.");
} else {
System.out.println(year + " is not a leap year.");
}
}
}
}
But now I want to repeat this code. I've seen repeating code snippets before, and I can use just about any successfully, but this one is giving me trouble.
import java.util.Scanner;
public class LeapUpgrade
{
public static void main(String[] args)
{
String another = "y";
int year;
Scanner scan = new Scanner(System.in);
while (another.equalsIgnoreCase("y"))
{
System.out.println("Enter year: ");
year = scan.nextInt();
if ((year % 4 == 0) && year % 100 != 0)
{
System.out.println(year + " is a leap year.");
System.out.print("test another (y/n)? ");
another = scan.nextLine();
}
else if ((year % 4 == 0) && (year % 100 == 0)
&& (year % 400 == 0))
{
System.out.println(year + " is a leap year.");
System.out.print("test another (y/n)? ");
another = scan.nextLine();
}
else
{
System.out.println(year + " is not a leap year.");
System.out.print("test another (y/n)? ");
another = scan.nextLine();
}
}
}
}
What am I doing wrong here?
Thanks in advance for your help and don't judge.
To avoid repetition, just encapsulate the lines of code in a method
public static boolean isLeapYear(int year){
return (year % 400 == 0) || ((year % 4 == 0) && (year % 100 != 0);
}
You can then call it like this
if(LeapYear.isLeapYear(year)){
System.out.println("Leap year");
}else{
System.out.println("Not a leap year");
}
EDIT: See Rohan's answer. It's better for the sake of modularity and cleanliness/readability of code.
When you want to do something multiple times you typically just need a loop. As a hint, your loop should enclose this part of your code:
year = scan.nextInt();
if ((year % 4 == 0) && year % 100 != 0) {
System.out.println(year + " is a leap year.");
} else if ((year % 4 == 0) && (year % 100 == 0) && (year % 400 == 0)) {
System.out.println(year + " is a leap year.");
} else {
System.out.println(year + " is not a leap year.");
}
I'll leave the type of loop and conditions to you.

Java Valid Dates and JOptionPane

Noob here so bear with me..I was working on a Java program that takes the users input from the JoptionPane, and uses a set of if-else statements to verify the date while considering the leap years. The problem I seem to be having when it runs is that it validates dates that aren't possible. For example, 2/29/2014, it says it's a valid date, but in reality it isn't.
Insight on this issue would be highly appreciated.
import java.util.Arrays;
import javax.swing.JOptionPane;
public class vaildDate {
public static void main(String[] args) {
// TODO Auto-generated method stub
int month, day, year;
String userInput = JOptionPane.showInputDialog("Enter a valid date in mm/dd/yyyy format: ");
String [] date = userInput.split("/");
String mm = date[0];
String dd = date [1];
String yyyy = date [2];
month = Integer.parseInt(mm);
day = Integer.parseInt(dd);
year = Integer.parseInt(yyyy);
System.out.println(mm+dd+yyyy);
boolean validLeapYear;
boolean validDate;
if(month>=1 && month <=12&& day>=1 && day<=31)
{
if(month == 4 || month == 9 || month == 6 || month == 11 && day <= 30)
{
validDate = true;
}
if(( month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 11 || month == 12) && (day <= 31))
{
validDate = true;
}
else{
validDate =false;
}
if((year % 400 == 0 ) || (year % 4 == 0) && (year % 100 != 0))
{
validLeapYear = true;
}
if ((month == 2 && day == 29) && (validLeapYear = false ))
{
validDate = false;
}
if((month == 2 && day <= 29) && (validLeapYear = true ))
{
validDate = true;
}
if(validDate = true)
{
JOptionPane.showMessageDialog(null, month +"/"+day+"/"+year+" is a valid date");
}
else if(validDate = false) {
JOptionPane.showMessageDialog(null,"Your date is invalid");
}
}
}
}
Instead of equating booleans your are assigning the values which return the results of your assignment.
For example:
if (validDate = true)
The above statement would return true. Instead, in all your boolean checks just validate the boolean value as is.
if (validDate)
To remove the compiler errors, you can initialize your 2 boolean vars to false.
You changed code would look something like:
public static void main(String[] args) {
// TODO Auto-generated method stub
int month, day, year;
String userInput = JOptionPane
.showInputDialog("Enter a valid date in mm/dd/yyyy format: ");
String[] date = userInput.split("/");
String mm = date[0];
String dd = date[1];
String yyyy = date[2];
month = Integer.parseInt(mm);
day = Integer.parseInt(dd);
year = Integer.parseInt(yyyy);
System.out.println(mm + dd + yyyy);
boolean validLeapYear = false;
boolean validDate = false;
if (month >= 1 && month <= 12 && day >= 1 && day <= 31) {
if (month == 4 || month == 9 || month == 6 || month == 11
&& day <= 30) {
validDate = true;
}
if ((month == 1 || month == 3 || month == 5 || month == 7
|| month == 8 || month == 11 || month == 12)
&& (day <= 31)) {
validDate = true;
} else {
validDate = false;
}
if ((year % 400 == 0) || (year % 4 == 0) && (year % 100 != 0)) {
validLeapYear = true;
}
if ((month == 2 && day == 29) && (!validLeapYear)) {
validDate = false;
}
if ((month == 2 && day <= 29) && (validLeapYear)) {
validDate = true;
}
if (validDate) {
JOptionPane.showMessageDialog(null, month + "/" + day + "/"
+ year + " is a valid date");
}
else if (!validDate) {
JOptionPane.showMessageDialog(null, "Your date is invalid");
}
}
}
A quick search on Google shows there are easier ways to validate a date. Please see this one:
http://www.mkyong.com/java/how-to-check-if-date-is-valid-in-java/
It uses the date parse and catches the exception if the date is not valid (cannot be parsed).
If you want to stick with your algorithm, I suggest to use an IDE like Eclipse and debug set by step while keeping a look on the value of your variables. You clearly have an algorithm problem, which will become obvious while debugging.
Hope that helps.

Test an int variable with a boolean in Java

I am still learning Java and am stuck and getting errors. Can someone help with a solution of how the best way to do this would be.
import java.util.Scanner;
public class LeapYear2 {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int year;
year = scan.nextInt();
boolean boolVar1,boolVar2,boolVar3;
boolVar1 = (year / 4);
boolVar2 = (year / 100);
boolVar3 = (year / 400);
if (boolVar1 == true && boolVar2 == true && boolVar3 == true)
{
System.out.println("This is a leap year.");
}
else if (boolVar1 == true && boolVar2 == true && boolVar3 != true)
{
System.out.println("This is not a leap year.");
}
else if (boolVar1 == true)
{
System.out.println("This is a leap year.");
}
else
{
System.out.println("This is not a leap year.");
}
}
}
If you want to know whether an int value is evenly divisible by another, you can do this:
boolVar1 = year % 4 == 0;
boolVar2 = year % 100 == 0;
boolVar3 = year % 400 == 0;
In Java, integer and boolean values are not interchangeable (unlike languages like C where 0 is false and any non-zero value is considered true). You need to use a comparison operator like ==. The % operator is the remainder function, which (from the rest of your code) looks like what you want to be using.
P.S. In the future, when you are asking about how to deal with errors, it would be very helpful if you posted the error message(s) in your question.
P.P.S. You should get in the habit of giving your variables meaningful names. For example, I would replace boolVar1 with divisibleBy4, etc. This will save you lots of headaches when you start writing more complex code.
Also, as others have pointed out, with a boolean variable b, recommended Java style is to use
if (...b...)
instead of
if (...b == true...)
and
if (...!b...)
instead of
if (...b == false...)
You need an explicit comparison to make an expression boolean. You do not need an explicit comparison with true on booleans, so the code should be as follows:
boolean boolVar1,boolVar2,boolVar3;
boolVar1 = (year % 4) == 0;
boolVar2 = (year % 100) == 0;
boolVar3 = (year % 400) == 0;
if (boolVar1 && boolVar2 && boolVar3)
{
System.out.println("This is a leap year.");
}
else if (boolVar1 && boolVar2 && !boolVar3)
{
System.out.println("This is not a leap year.");
}
else if (boolVar1)
{
System.out.println("This is a leap year.");
}
else
{
System.out.println("This is not a leap year.");
}
Note that boolVar != true and boolVar == false is equivalent to !boolVar.
use the modulo method for this.
if(year % 4 == 0){
System.out.println("This is a leap year.");
}
and so on. From what I can see you do not need to declare 3 separate int types for this. Just reuse this in each conditional statement.
You do not need all those booleans. You can simply test:
if ((year % 4 == 0) && (year % 100 != 0)){
System.out.println(year + " is a leap year.");
}
else if (year % 400 == 0){
System.out.println(year + " is a leap year.");
}
else {
System.out.println(year + " is not a leap year.");
}
rather than calculating so many conditions just put the following code
if(year%4==0)
System.out.println("The given year is leap year");
else
System.out.println("The given year is not leap year");
There is no situation where you stuck up between int value and boolean.
Use this code
boolVar1 = (year % 4) == 0;
boolVar2 = (year % 100) ==0;
boolVar3 = (year % 400) == 0;
Note that the original version would have worked in C.

Categories