41

我正在关注“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.");
    }

}

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

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

我的代码有什么问题还是应该使用本书提供的代码?

编辑 :: 上述两个代码都可以正常工作,我想问的是哪个代码是计算闰年的最佳方法。

4

21 回答 21

98

正确的实现是:

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

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

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;
  }
}
于 2009-06-20T10:21:47.517 回答
38

java.time.Year::isLeap

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

java.time.Year.of(year).isLeap();
于 2016-05-22T22:32:21.430 回答
29

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

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

在单元测试中

assertTrue(isLeapYear(2000));
assertTrue(isLeapYear(1904));
assertFalse(isLeapYear(1900));
assertFalse(isLeapYear(1901));
于 2009-06-20T09:57:13.900 回答
11

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

(year % 400 == 0) || ((year % 4 == 0) && (year % 100 != 0))
于 2010-05-28T20:40:00.050 回答
11
new GregorianCalendar().isLeapYear(year);
于 2015-02-17T07:45:28.597 回答
6

最有效的闰年测试:

if ((year & 3) == 0 && ((year % 25) != 0 || (year & 15) == 0))
{
    /* leap year */
}

这是我在https://stackoverflow.com/a/11595914/733805上的详细回答的摘录

于 2012-07-21T23:53:59.933 回答
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;
}

其中 changeYear 是儒略历变为公历 (1582) 的年份。

儒略历每四年指定闰年,而公历省略不能被 400 整除的世纪年。

公历文档中,您可以找到有关它的更多信息。

于 2016-06-01T14:18:16.667 回答
5

如果您使用的是 java8 :

java.time.Year.of(year).isLeap()

上述方法的Java实现:

public static boolean isLeap(long year) {
        return ((year & 3) == 0) && ((year % 100) != 0 || (year % 400) == 0);
    }
于 2017-03-04T07:52:52.723 回答
3

在软件中重复几乎总是错误的。在任何工程学科中,形式都应该遵循功能,并且对于具有两种可能路径的事物具有三个分支-要么是闰年,要么不是闰年。

在一行上进行测试的机制没有这个问题,但通常最好将测试分成一个函数,该函数接受一个表示年份的 int 并返回一个表示该年份是否为闰年的布尔值. 这样你就可以用它做一些其他的事情,打印到控制台上的标准输出,并且可以更容易地测试它。

在已知超出其性能预算的代码中,通常会安排测试以使它们不是多余的,并按照提前返回的顺序执行测试。维基百科的例子就是这样做的——对于大多数年份,您必须计算模 400,100 和 4,但对于少数情况,您只需要模 400 或 400 和 100。这是性能方面的一个小优化(充其量,只有百分之一)输入受到影响),但这也意味着代码的重复次数更少,程序员输入的次数也更少。

于 2009-06-20T10:07:16.800 回答
2

您可以为此向GregorianCalendar类询问:

boolean isLeapyear = new GregorianCalendar().isLeapYear(year);
于 2016-06-01T14:46:28.583 回答
1

随着课程:TestMyCode Programming assignment evaluator,其中一个练习就是这种问题,我写了这个答案:

import java.util.Scanner;

public class LeapYear {

    public static void main(String[] args) {
        Scanner reader = new Scanner(System.in);
        System.out.println("Type a year: ");

        int year = Integer.parseInt(reader.nextLine());

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

    }
}
于 2018-05-31T15:06:57.950 回答
0

这就是我想出的。有一个附加功能可以检查 int 是否超过了施加异常的日期(年 100 美元,年 %400)。在 1582 年之前,这些例外情况并不存在。

import java.util.Scanner;

public class lecture{


public static void main(String[] args) {
    boolean loop=true;
    Scanner console = new Scanner( System.in );
    while (loop){
        System.out.print( "Enter the year: " );

        int year= console.nextInt();
        System.out.println( "The year is a leap year: "+ leapYear(year) );
        System.out.print( "again?: " );
        int again = console.nextInt();
        if (again == 1){
            loop=false;
        }//if
    }
}
public static boolean leapYear ( int year){
    boolean leaped = false;
    if (year%4==0){
        leaped = true;
        if(year>1582){
            if (year%100==0&&year%400!=0){
                leaped=false;
            }
        }
    }//1st if
    return leaped;
}
} 
于 2013-09-23T04:47:52.277 回答
0
public static void main(String[] args)
{

String strDate="Feb 2013";
        String[] strArray=strDate.split("\\s+");        

        Calendar cal = Calendar.getInstance();
        cal.setTime(new SimpleDateFormat("MMM").parse(strArray[0].toString()));
        int monthInt = cal.get(Calendar.MONTH);
        monthInt++;
        cal.set(Calendar.YEAR, Integer.parseInt(strArray[1]));          
        strDate=strArray[1].toString()+"-"+monthInt+"-"+cal.getActualMaximum(Calendar.DAY_OF_MONTH);

        System.out.println(strDate);    



}
于 2013-10-23T14:41:31.397 回答
0
    import java.util.Scanner;

    public class LeapYear {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner input = new Scanner(System.in);
        System.out.print("Enter the year then press Enter : ");
        int year = input.nextInt();

        if ((year < 1580) && (year % 4 == 0)) {
            System.out.println("Leap year: " + year);
        } else {
            if ((year % 4 == 0) && (year % 100 != 0) || (year % 400 == 0)) {
                System.out.println("Leap year: " + year);
            } else {
                System.out.println(year + " not a leap year!");
            }

        }
    }
}
于 2014-02-22T19:19:58.117 回答
0

正如维基百科所说的闰年算法应该是

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

这是一个如何检查闰年的示例程序。

于 2015-05-24T15:45:47.357 回答
0

您的代码,因为它没有额外的类,似乎不适用于通用 java。这是一个可以在任何地方工作的简化版本,更倾向于您的代码。

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

您的代码在上下文中也同样有效,但请注意书本代码始终有效,并且经过了彻底的测试。不是说你的不是。:)

于 2016-01-21T16:37:00.207 回答
0

让java闰年更容易理解的最简单方法enter code here

import  java.util.Scanner;

类 que19{

public static void main(String[] args) {

    Scanner input=new Scanner(System.in);

    double a;

    System.out.println("enter the year here ");
    a=input.nextDouble();
    if ((a % 4 ==0 ) && (a%100!=0) || (a%400==0)) {
        System.out.println("leep year");

    }
    else {
        System.out.println("not a leap year");
    }
}

}

于 2017-11-12T14:13:59.680 回答
0

这个答案很好,但在基督之前几年(使用预测的公历)它不会起作用。如果您希望它在 BC 年内工作,请使用以下改编:

public static boolean isLeapYear(final int year) {
    final Calendar cal = Calendar.getInstance();
    if (year<0) {
        cal.set(Calendar.ERA, GregorianCalendar.BC);
        cal.set(Calendar.YEAR, -year);
    } else
        cal.set(Calendar.YEAR, year);
    return cal.getActualMaximum(Calendar.DAY_OF_YEAR) > 365;
}

您可以通过考虑假定公历为闰年 -5 年(即公元前 4 年)来验证这一点。与 -1 年(公元 1 年之前的一年)相同。链接到答案不处理这种情况,而上述改编的代码可以。

于 2018-12-10T20:07:20.267 回答
0

在 Kotlin 中回答:

fun isLeapYear(year: Int): Boolean =
    when {
        year % 4 != 0 -> false
        year % 100 == 0 -> year % 400 == 0
        else -> true
    }
于 2021-09-12T00:21:36.657 回答
-1
import javax.swing.*;
public class LeapYear {
    public static void main(String[] args) {
    int year;
String yearStr = JOptionPane.showInputDialog(null, "Enter radius: " );

year = Integer.parseInt( yearStr );

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

 if(isLeapYear){ 
JOptionPane.showMessageDialog(null, "Leap Year!"); 
 }  
 else{
JOptionPane.showMessageDialog(null, "Not a Leap Year!"); 
    }
    }
    }
于 2013-04-15T17:54:20.173 回答
-2
boolean leapYear = ( ( year % 4 ) == 0 );
于 2012-12-06T20:02:03.827 回答