用于计算闰年的Java代码

Ibn*_*eed 34 java leap-year acm-java-libraries

我正在关注"Java的艺术与科学"一书,它展示了如何计算闰年.本书使用ACM Java Task Force的库.

这是书籍使用的代码:

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

}
Run Code Online (Sandbox Code Playgroud)

现在,这就是我计算闰年的方法.

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.");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我的代码有什么问题,或者我应该使用本书提供的代码吗?

编辑::以上两个代码都运行正常,我想问的是哪个代码是计算闰年的最佳方法.

cle*_*tus 84

正确的实施是:

public static boolean isLeapYear(int year) {
  Calendar cal = Calendar.getInstance();
  cal.set(Calendar.YEAR, year);
  return cal.getActualMaximum(Calendar.DAY_OF_YEAR) > 365;
}
Run Code Online (Sandbox Code Playgroud)

但是如果你要重新发明这个轮子那么:

public static boolean isLeapYear(int year) {
  if (year % 4 != 0) {
    return false;
  } else if (year % 400 == 0) {
    return true;
  } else if (year % 100 == 0) {
    return false;
  } else {
    return true;
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 更好的是 - `返回新的GregorianCalendar(年,1,1).isLeapYear();` (6认同)
  • +1使用库代码.我建议添加一个注释是因为400是100的倍数,你在100之前测试400而不是原始代码. (3认同)

Pet*_*rey 24

我建议你把这段代码放到一个方法中并创建一个单元测试.

public static boolean isLeapYear(int year) {
    assert year >= 1583; // not valid before this date.
    return ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
}
Run Code Online (Sandbox Code Playgroud)

在单元测试中

assertTrue(isLeapYear(2000));
assertTrue(isLeapYear(1904));
assertFalse(isLeapYear(1900));
assertFalse(isLeapYear(1901));
Run Code Online (Sandbox Code Playgroud)

  • @jcw 1583年是公历的第一年。不同的国家在不同的年份采用它,使1583年和采用它的年份更加复杂。(有关如何混淆的想法,请参见http://en.wikipedia.org/wiki/February_30。)在任何情况下,在创建公历之前都不要使用公历。 (2认同)

bow*_*ore 19

java.time.Year::isLeap

我想java.timeYear类和isLeap方法添加新的方法:

java.time.Year.of(year).isLeap();
Run Code Online (Sandbox Code Playgroud)

  • 今年是闰年吗?(使用java 8)`Year.now().isLeap()` (3认同)

小智 9

来自维基百科的伪代码翻译成最紧凑的Java

(year % 400 == 0) || ((year % 4 == 0) && (year % 100 != 0))
Run Code Online (Sandbox Code Playgroud)


小智 9

new GregorianCalendar().isLeapYear(year);
Run Code Online (Sandbox Code Playgroud)


Kev*_*ice 6

最有效的闰年测试:

if ((year & 3) == 0 && ((year % 25) != 0 || (year & 15) == 0))
{
    /* leap year */
}
Run Code Online (Sandbox Code Playgroud)

这是我在/sf/answers/811714011/上的详细答案的摘录


Fel*_*ade 5

来自JAVA的GregorianCalendar源代码:

/**
 * 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;
}
Run Code Online (Sandbox Code Playgroud)

其中changeYear是Julian Calendar成为公历的年份(1582年).

朱利安历法规定了每四年一次的闰年,而格里高利历则省略了不能被400整除的世纪年.

Gregorian Calendar文档中,您可以找到有关它的更多信息.


Mah*_*raa 5

如果您使用的是 java8 :

java.time.Year.of(year).isLeap()
Run Code Online (Sandbox Code Playgroud)

上述方法的Java实现:

public static boolean isLeap(long year) {
        return ((year & 3) == 0) && ((year % 100) != 0 || (year % 400) == 0);
    }
Run Code Online (Sandbox Code Playgroud)