Java Code for calculating Leap Year

2019-01-01 07:35发布

I am following "The Art and Science of Java" book and it shows how to calculate a leap year. The book uses ACM Java Task Force's library.

Here is the code the books uses:

import acm.program.*;

public class LeapYear extends ConsoleProgram {
    public void run()
    {

        println("This program calculates leap year.");
        int year = readInt("Enter the year: ");     

        boolean isLeapYear = ((year % 4 == 0) && (year % 100 != 0) || (year % 400 == 0));

        if (isLeapYear)
        {
            println(year + " is a leap year.");
        } else
            println(year + " is not a leap year.");
    }

}

Now, this is how I calculated the leap year.

import acm.program.*;

public class LeapYear extends ConsoleProgram {
    public void run()
    {

        println("This program calculates leap year.");
        int year = readInt("Enter the year: ");

        if ((year % 4 == 0) && year % 100 != 0)
        {
            println(year + " is a leap year.");
        }
        else if ((year % 4 == 0) && (year % 100 == 0) && (year % 400 == 0))
        {
            println(year + " is a leap year.");
        }
        else
        {
            println(year + " is not a leap year.");
        }
    }
}

Is there anything wrong with my code or should i use the one provided by the book ?

EDIT :: Both of the above code works fine, What i want to ask is which code is the best way to calculate the leap year.

21条回答
孤独总比滥情好
2楼-- · 2019-01-01 07:39

They look the same to me, though note that this line in your code has some redundancy:

else if ((year % 4 == 0) && (year % 100 == 0) && (year % 400 == 0))

could be replaced by:

else if (year % 400 == 0)

If a number is a multiple of 400 then it's automatically also a multiple of 100 and 4.

edit: (7 years later!)

Please note that the above assumes the presence of the preceding if ((year % 4 == 0) && year % 100 != 0) from the original question!

cletus's answer should be the accepted one: https://stackoverflow.com/a/1021373/8331

(I'd delete my own answer, but I can't since it's the accepted on)

查看更多
柔情千种
3楼-- · 2019-01-01 07:40

As wikipedia states algorithm for the leap year should be

(((year%4 == 0) && (year%100 !=0)) || (year%400==0))  

Here is a sample program how to check for leap year.

查看更多
宁负流年不负卿
4楼-- · 2019-01-01 07:42

Your code, as it is, without an additional class, does not appear to work for universal java. Here is a simplified version that works anywhere, leaning more towards your code.

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.");
            }
        }
    }
}

Your code, in context, works just as well, but note that book code always works, and is tested thoroughly. Not to say yours isn't. :)

查看更多
十年一品温如言
5楼-- · 2019-01-01 07:43

It's almost always wrong to have repetition in software. In any engineering discipline, form should follow function, and you have three branches for something which has two possible paths - it's either a leap year or not.

The mechanism which has the test on one line doesn't have that issue, but generally it would be better to separate the test into a function which takes an int representing a year and returns a boolean representing whether or not the year is a leap year. That way you can do something with it other that print to standard output on the console, and can more easily test it.

In code which is known to exceed its performance budget, it's usual to arrange the tests so that they are not redundant and perform the tests in an order which returns early. The wikipedia example does this - for most years you have to calculate modulo 400,100 and 4, but for a few you only need modulo 400 or 400 and 100. This is a small optimisation in terms of performance ( at best, only one in a hundred inputs are effected ), but it also means the code has less repetition, and there's less for the programmer to type in.

查看更多
旧人旧事旧时光
6楼-- · 2019-01-01 07:45

From JAVA's GregorianCalendar sourcecode:

/**
 * Returns true if {@code year} is a leap year.
 */
public boolean isLeapYear(int year) {
    if (year > changeYear) {
        return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
    }

    return year % 4 == 0;
}

Where changeYear is the year the Julian Calendar becomes the Gregorian Calendar (1582).

The Julian calendar specifies leap years every four years, whereas the Gregorian calendar omits century years which are not divisible by 400.

In the Gregorian Calendar documentation you can found more information about it.

查看更多
看风景的人
7楼-- · 2019-01-01 07:45

You can ask the GregorianCalendar class for this:

boolean isLeapyear = new GregorianCalendar().isLeapYear(year);
查看更多
登录 后发表回答