The code works when the first year is a leap year so if I said the year was 2004 it would return 2008, but when the starting year is not a leap year, it returns nothing. How would I output that if, for ex: the given year was 2001, 2002, or 2003, the next leap year would be 2004. I know the while loop makes sense but I don't know what to put inside it. ALSO I can only use basic java formatting so no inputted classes like java.time.Year
public static boolean leapYear(int year) {
boolean isLeap = true;
if (year % 4 == 0) {
if (year % 100 == 0) {
if (year % 400 == 0)
isLeap = true;
else
isLeap = false;
} else
isLeap = true;
} else {
isLeap = false;
}
return isLeap;
}
public static int nextLeapYear(int year) {
int nextLeap = 0;
if (leapYear(year)) {
nextLeap = nextLeap + 4;
} else {
while (!leapYear(year)) {
nextLeap++;
}
nextLeap += 1;
}
year += nextLeap;
return year;
}
Granted this doesn't take much processing. But if you want to increase the efficiency of your program you might consider the following:
All leap years must be divisible by 4. But not all years divisible by 4 are leap years. So first, check for not divisible by 4. That will be 75% of the cases. In that event, return false.
if (year % 4 != 0) {
return false;
}
As you continue, the year must be divisible by 4 so just make certain it is not a century year. This will be evaluated 25% of the time and will return true 24% of the time.
if (year % 100 != 0) {
return true;
}
lastly, the only category not checked are years divided by 400. If we got here in the logic, then it must be a century year. So return accordingly. This will evaluate to true .25% of the time.
return year % 400 == 0;
Your code is broken in multiple ways:
You say: If the given year is a leap year, then the next leap year will be 4 years later. This is false. If you pass in 1896, your algorithm returns 1900, but this is wrong; whilst 1896 is a leap year, 1900 is not.
Your isLeapYear code would be miles easier to read if you early-exit. That method should have a lot of return statements and fall less indentation.
Your while loop will keep asking the same question over and over, and if you ask the same question to a stable method (and your isLeapYear method is stable), you get the same answer, resulting in an infinite loop. Presumably, you don't want while(!leapYear(year)), you want while(!leapYear(year + nextLeap)), and you don't want to increment nextLeap once more after the while loop.
in fact, your edge case of: If the stated year is already a year, add 4 - is not necessary at all. Think about it: You can just eliminate that if/else part. Your code will just be nextLeap, that while loop, and a return statement. a 3-liner, if you do right.
EDIT: I figured it out yay!
for anybody struggling w/ this, this is what worked for me :)
public static boolean leapYear(int year) {
if(year % 4 == 0)
{
if( year % 100 == 0)
{
// year is divisible by 400, hence the year is a leap year
if ( year % 400 == 0)
return true;
else
return false;
}
else
return true;
}
else
return false;
}
public static int nextLeapYear (int year) {
int nextLeap = 0;
while(leapYear(year + nextLeap) == false){
nextLeap++;
}
if(leapYear(year) == true)
nextLeap += 4;
year += nextLeap;
return year;
}
Every year that is exactly divisible by four is a leap year, except
for years that are exactly divisible by 100, but these centurial years
are leap years if they are exactly divisible by 400. For example, the
years 1700, 1800, and 1900 are not leap years, but the years 1600 and
2000 are.
- United States Naval Observatory
You can greatly simplify the function, leapYear as shown below:
public static boolean leapYear(int year) {
return year % 400 == 0 || (year % 4 == 0 && year % 100 != 0);
}
Demo:
public class Main {
public static void main(String[] args) {
// Test
System.out.println(leapYear(1999));
System.out.println(leapYear(2000));
System.out.println(leapYear(1900));
System.out.println(leapYear(1904));
}
public static boolean leapYear(int year) {
return year % 400 == 0 || (year % 4 == 0 && year % 100 != 0);
}
}
Output:
false
true
false
true
Then, you can use it in the function, nextLeapYear as shown below:
public class Main {
public static void main(String[] args) {
// Test
System.out.println(nextLeapYear(1999));
System.out.println(nextLeapYear(2000));
System.out.println(nextLeapYear(2001));
}
public static int nextLeapYear(int year) {
// If year is already a leap year, return year + 4
if (leapYear(year)) {
return year + 4;
}
// Otherwise, keep incrementing year by one until you find a leap year
while (!leapYear(year)) {
year++;
}
return year;
}
public static boolean leapYear(int year) {
return year % 400 == 0 || (year % 4 == 0 && year % 100 != 0);
}
}
Output:
2000
2004
2004
In production code, you should use the OOTB (Out-Of-The-Box) class, java.time.Year to deal with a year.
import java.time.Year;
public class Main {
public static void main(String[] args) {
// Test
System.out.println(nextLeapYear(1999));
System.out.println(nextLeapYear(2000));
System.out.println(nextLeapYear(2001));
}
public static int nextLeapYear(int year) {
Year yr = Year.of(year);
// If year is already a leap year, return year + 4
if (yr.isLeap()) {
return yr.plusYears(4).getValue();
}
// Otherwise, keep incrementing year by one until you find a leap year
while (!yr.isLeap()) {
yr = yr.plusYears(1);
}
return yr.getValue();
}
}
Output:
2000
2004
2004
Learn more about the modern date-time API at Trail: Date Time.
It seems it not easy to get nextLeapYear() 100 % correct. Allow me to suggest a simpler way of thinking about it that will also — so I believe — make it simpler to code correctly and/or fix any bug there may be.
Declare a variable candidateLeapYear to hold a year that we don’t yet know whether will be the next leap year after year. Initialize it to year + 1 since we know that the next leap year will need to be strictly greater than year. In a loop test whether candidateLeapYear is a leap year (use the other method), and as long as it isn’t, increment by 1. When the loop terminates, candidateLeapYear holds the next leap year. Return it.
Related
This question already has answers here:
Java Code for calculating Leap Year
(22 answers)
Closed 3 years ago.
so the code works but some years which should be leap years are not like 2008 is showing its not a leap year which it was.
//is leap year if...
if ((whichYear % 4 == 0) && (whichYear % 100 == 0) && (whichYear % 400 == 0))
{
isLeapYear = true;
daysLeftInYear = 366;
System.out.println("true " + daysLeftInYear);
}
else
{
isLeapYear = false;
daysLeftInYear = 365;
System.out.println("false " + daysLeftInYear);
}
The easiest way is to just break it down into two possibilities.
If (year % 100 == 0) {
// if century year
} else {
// if not century year.
}
The rest is up to you.
Well of course it won't work with 2008 :) Because you defined leap years as being divisible by 4 AND divisible by 100 AND divisible by 400 :) With this definition only every 400th year will be a leap year, for example 1600.
The correct definition of a leap year is: Divisible by 4 AND if it is divisible by 100, then also divisible by 400. For example 1700 is not a leap year, but 1200 is.
So in terms of Java this would lead to:
int year; // initialize it with some year
boolean leapYear = year % 4 == 0 && ((year % 100 == 0) == (year % 400 == 0))
I am trying to write a program in Java (this is a school assignment that tells you what day of the week a certain date is. (The date should be written on the form yyyy-mm-dd.) I thought I had come up with a solution with the code below, but then I found an error.
When you run the code, and type in 1999-12-31 in the dialog, the program tells you that the entered date (1999-12-31) is a Friday. But when you type in the date 2000-01-01 (which is one day after 1999-12-31), the program tells you that the day is a Sunday! What happened with Saturday? A similar problem happens when you type in 2000-02-29 and 2000-03-01, they both give Wednesday as an answer!
What I have yet noticed, this error appears only when you enter a date between 2000-01-01 and 2000-02-29. I would be very grateful if someone could please help me to find the cause of the error and to solve the problem!
import static javax.swing.JOptionPane.*;
import static java.lang.Math.*;
public class DateCalc {
// Here, between the DateCalc class declaration and the main method, several methods used in the program are
// constructed.
// The method isLeapYear tests whether the entered year is a leap year or not.
private static boolean isALeapYear(int year) {
// If the year is a multiple of 4 and not a multiple of 100, or a multiple of 400, then it is a leap year.
if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
return true;
}
else {
return false;
}
}
// A method that tests whether a given string is written as a valid date.
private static boolean isAValidDate(int year, int month, int day) {
int maxValidYear = 9999;
int minValidYear = 1754;
if (year > maxValidYear || year < minValidYear) {
return false;
}
if (month < 1 || month > 12) {
return false;
}
if (day < 1 || day > 31) {
return false;
}
// Handle the February Month
if (month == 2) {
if (isALeapYear(year)) {
return (day <= 29); // This statement is true if the value of the day is less than or equal to 29 if the month is February within a leap year.
// Otherwise the statement is false and the method will return the boolean value false.
}
else {
return (day <= 28); // This statement is true if the value of the day is less than or equal to 28 if the month is February within a non-leap year.
// Otherwise the statement is false and the method will return the boolean value false.
}
}
// Month of April, June, September and November must have number of days less than or equal to 30.
if (month == 4 || month == 6 || month == 9 || month == 11) {
return (day <= 30);
}
return true;
}
// A method that calculates the day number within the year.
private static int dayNumberWithinYear(int year, int month, int day) {
// An array which stores the number of days in the different months (when the year is not a leap year).
// (Index 0 is the number of days in January, index 1 is the number of days in February, etc.)
int[] monthStructure = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
// If the entered year is a leap year, then the monthStructure array will be initialized with an extra day in February, i.e the leap day.
if (isALeapYear(year)) {
monthStructure[1] = 29;
}
int sumDaysInPreviousMonths = 0;
int daysInTheCurrentMonth = day;
int dayNumber = 0;
// Loops through all the months (index 0 is January, index 1 is February, etc.).
for (int i = 0; i < month - 1; i++) {
sumDaysInPreviousMonths += monthStructure[i];
}
dayNumber = sumDaysInPreviousMonths + daysInTheCurrentMonth;
return dayNumber;
}
// A method that decides the day of the week of an entered date.
private static void weekDay(int year, int month, int day) {
// The number of days that have passed since January 1, 1754, excluding the days of the entered year and
// excluding the leap days.
int sumDaysInOrdinaryYears = (year - 1754) * 365;
int sumLeapDaysInLeapYears = 0;
// Suppose the entered year is n. The for-loop goes through all the years from year n-1 to year 1754, and
// checks if the current year in the loop is a leap year. The number of leap years between year 1754 and n-1
// is equal to the number of days that will get added (beside from the days in ordinary years) to the total
// days from January 1, 1754 to the entered date.
for (; year > 1754; year -= 1) {
if (isALeapYear(year)) {
sumLeapDaysInLeapYears += 1;
}
}
// The sum of all days from year 1754 to year n-1 (if the entered year is n), is equal to the sum of days in
// the ordinary years and the leap days in the years.
int sumDaysInEveryYearExcludingTheEntered = sumDaysInOrdinaryYears + sumLeapDaysInLeapYears;
int sumDaysInTotalYears = sumDaysInEveryYearExcludingTheEntered + dayNumberWithinYear(year, month, day);
int weekDay = sumDaysInTotalYears % 7;
if (weekDay == 0) {
showMessageDialog(null, "The date is a monday.");
}
else if (weekDay == 1) {
showMessageDialog(null, "The date is a tuesday.");
}
else if (weekDay == 2) {
showMessageDialog(null, "The date is a wednesday.");
}
else if (weekDay == 3) {
showMessageDialog(null, "The date is a thursday.");
}
else if (weekDay == 4) {
showMessageDialog(null, "The date is a friday.");
}
else if (weekDay == 5) {
showMessageDialog(null, "The date is a saturday.");
}
// If weekDay == 6
else {
showMessageDialog(null, "The date is a sunday.");
}
}
public static void main(String[] args) {
// This is step 3 in the laboratory instruction.
while (true) {
String date = showInputDialog("Please, enter a date on the form yyyy-mm-dd");
// If the user clicks 'Cancel' or clicks 'OK' when the dialog box is empty, the program will exit.
if (date == null || date.length() == 0) {
break;
}
int y = Integer.parseInt(date.substring(0,4));
int m = Integer.parseInt(date.substring(5,7));
int d = Integer.parseInt(date.substring(8));
if (!isAValidDate(y, m, d)) {
showMessageDialog(null, "Error! The entered date is invalid. " +
" Please enter a valid date on the form yyyy-mm-dd");
}
else {
weekDay(y, m, d);
}
}
}
}
Instead of asking us to debug through your entire code, perhaps consider LocalDate to get the desired result:
LocalDate ldt = LocalDate.parse("1999-12-31");
System.out.println(ldt.getDayOfWeek());
LocalDate ldt2 = LocalDate.parse("2000-01-01");
System.out.println(ldt2.getDayOfWeek());
Output:
FRIDAY
SATURDAY
The Problem is with finding the number of leap year. Your logic is counting the year 2000 also. The number of leap years should be same for 1999-12-31 and 2000-01-01. You need to consider year 2000 only if the month is greater than February. Increment the sumLeapDaysInLeapYears only if the input date is greater than Feb 28th
This question already has answers here:
Java Code for calculating Leap Year
(22 answers)
Closed 5 years ago.
import java.util.*;
public class LeapYear
{
public static void main (String[]args)
{
Scanner scan= new Scanner (System.in);
System.out.println("Please enter in the year");
int year=scan.nextInt();
if (year % 4 ==0)
{
{
if (year % 100 ==0);
else
System.out.println("The year,"+year+",is a leap year!");
}
if(year % 400==0)
System.out.println("The year, "+year+",is a leap year!");
}
else
System.out.println("The year, "+year+",is not a leap year!");
}
}
Hey everyone! Above is my code for a leap year program- It seems to work well, except whenever I enter a number such as 3000 or 300, the JVM just stops and shuts the terminal window. Could someone please guide as to why it's not accepting these numbers (Also, please forgive me that my code is not formatted properly- I'm new and trying to do the best I can)
NOTE: It is displaying all the right answers when I test 1900, 1996, 2004, 164, and 204 as years. It will simply not accept 300 or 3000.
Thanks Again!
check the following lines:
if (year % 100 ==0);
else
300 % 100 == 0, nothing is output.
You asked that we forgive your formatting, but it is your formatting that is leading you to miss the problem. Especially when you are first starting out, you will find it most helpful to understand what's going on if you are extremely diligent in your formatting. Suggestion: always include the braces, even when they are optional, and always provide the 'else' portion of every 'if' statement. Thus:
if (condition) {
action;
} else {
alternative action;
}
In your case, you will see in your lines 11 and 12 where you have syntacticly correct code, but very likely not what you meant. The opening brace on line 11 seems out of place and the semicolon at the end of line 12 is simply taking the place of the "action" that would take place if that condition were true.
if ((year % 4) == 0) {
// could be a leap year
if ((year % 100) == 0) {
// could be a leap year too
if ((year % 400) == 0) {
println("yes, this is a leap year ... divisible by 4, 100, AND 400");
} else {
// not a leap year ... divisible by 4 and 100, but NOT 400
}
} else {
println("yes, this is a leap year ... it's divisible by 4 but not 100");
}
} else {
// absolutely not a leap year
}
You can make your code more concise if you do this instead:
if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)) {
System.out.println("The year,"+year+",is a leap year!");
} else {
System.out.println("The year, "+year+",is not a leap year!");
}
Also, notice that this formula for calculating leap years only works for years after "1583".
This question already has an answer here:
Why is my leap year algorithm not working (Java)? [duplicate]
(1 answer)
Closed 8 years ago.
I am making a scanner object to get a year and test to see if it is a leap year. Just want some feedback. Is this right what I have? Thank you!
import java.util.Scanner;
public class Micro4
{
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
int testDate = input.nextInt();
boolean divFour = (((testDate % 4) == 0));
boolean divHundred = (((testDate % 100) != 0));
boolean divFourHundred = (((testDate % 400) != 0));
if (divFour && divHundred && divFourHundred) {
System.out.println(testDate + " is a leap year.");
} else {
System.out.println(testDate + " is not a leap year.");
}
}
}
The logic is slightly wrong. 2000 is a leap year, yet it isn't according to your program. The proper logic should've been:
if ((divFour && divHundred)||!divFourHundred) {
Also, as Dave Galvin suggested, do use better variable names to improve readability.
The trick is to put this into code:
A year is a leap year if it is divisible by 4, but century years are
not leap years unless they are divisible by 400.
I am checking if a (year is a multiple of 4 AND not a multiple of 100) OR (year is multiple of 400).
if((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
System.out.println("Leap");
else
System.out.println("Not leap.");
This question already has answers here:
Java Code for calculating Leap Year
(22 answers)
Closed 8 years ago.
Question from exam:
Write a Boolean expression for the following:
A is a leap year.
Any help would be appreciated!
A year is a leap year if it is divisible by 4 and not divisible by 100, but it is always one if it is divisible by 400. You can translate this to code literally:
int year = 2004;
boolean leap = ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
The modulo operator (%) gives you the remainder when dividing the numbers, so it is equal to 0 if the first number is divisible by the second.
As Bathsheba points out, this only works for the Gregorian Calendar (our modern system since 1582 in some countries or even later in others), if you want to handle years prior to this date, the code would be much more complicated and it would require some research for the exact rules at that time. In an exam, however, you should not need to worry about those.
http://en.wikipedia.org/wiki/Leap_year
from article pseudo code:
if year is not divisible by 4 then common year
else if year is not divisible by 100 then leap year
else if year is not divisible by 400 then common year
else leap year
if((A%4==0) && A%100!=0)||A%400==0)
You can use this boolean function to determine a leap year:
public static boolean IsLeapYear(int year)
{
if ((year % 4) == 0)
{
if ((year % 100) == 0)
{
if ((year % 400) == 0)
return true;
else
return false;
}
else
return true;
}
return false;
}
This follows the two rules to determine a leap year
First Rule: The year divisible by 4 is a leap year.
Second Rule: If the year is divisible by 100, then it is not a leap year. But If the year is divisible by 400, then it is a leap year.