finding next leap year java

874 Views Asked by At

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;
}
4

There are 4 best solutions below

0
On

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.

0
On

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;

2
On

Your code is broken in multiple ways:

  1. 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.

  2. 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.

  3. 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.

  4. 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.

2
On

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;

    }