计算闰年的Java代码

计算闰年的Java代码,java,leap-year,acm-java-libraries,Java,Leap Year,Acm Java Libraries,我正在阅读《Java的艺术与科学》一书,它展示了如何计算闰年。 这本书使用了ACM Java任务组的库 以下是本书使用的代码: import acm.program.*; public class LeapYear extends ConsoleProgram { public void run() { println("This program calculates leap year."); int year = readInt("Ente

我正在阅读《Java的艺术与科学》一书,它展示了如何计算闰年。 这本书使用了ACM Java任务组的库

以下是本书使用的代码:

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.");
        }
    }
}
我的代码有什么问题吗?还是应该使用书中提供的代码


编辑::以上两种代码都很好,我想问的是哪种代码是计算闰年的最佳方法

我建议您将此代码放入一个方法中,并创建一个单元测试

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

在软件中重复几乎总是错误的。在任何工程学科中,形式都应该遵循功能,你有三个分支,它们有两条可能的路径——要么是闰年,要么不是

在一行上有测试的机制没有这个问题,但是通常最好将测试分离成一个函数,该函数取一个int表示一年,并返回一个布尔值表示一年是否是闰年。这样,您就可以使用它在控制台上打印到标准输出,并且可以更轻松地测试它


在已知超过其性能预算的代码中,通常会安排测试,使其不冗余,并以提前返回的顺序执行测试。wikipedia的例子就是这样做的——在大多数情况下,你需要计算模400100和4,但在少数情况下,你只需要模400或模400和100。就性能而言,这是一个小小的优化(充其量只有百分之一的输入受到影响),但这也意味着代码的重复性更少,程序员输入的代码也更少

正确的实现方式是:

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

维基百科中的伪代码被翻译成最紧凑的Java

(year % 400 == 0) || ((year % 4 == 0) && (year % 100 != 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;
}
} 
import java.util.Scanner;
公共课年{
公共静态void main(字符串[]args){
//TODO自动生成的方法存根
扫描仪输入=新扫描仪(System.in);
System.out.print(“输入年份,然后按Enter:”);
int year=input.nextInt();
如果((年份<1580)和&(年份%4==0)){
System.out.println(“闰年:+年”);
}否则{
如果((第%4年==0)和&(第%100年!=0)| |(第%400年==0)){
System.out.println(“闰年:+年”);
}否则{
System.out.println(年份+“不是闰年!”);
}
}
}
}
作为国家,闰年的算法应该是

(((year%4 == 0) && (year%100 !=0)) || (year%400==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.");
            }
        }
    }
}
您的代码在上下文中也同样有效,但请注意,书本代码始终有效,并且经过彻底测试。更不用说你的不是

java.time.Year::isLeap
我想在类和方法中添加一种新的方法:


来自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整除的世纪

在中,您可以找到有关它的更多信息。

您可以向全班询问:

boolean isLeapyear = new GregorianCalendar().isLeapYear(year);

如果您使用的是java8:

java.time.Year.of(year).isLeap()
上述方法的Java实现:

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

使java闰年更容易理解的最简单方法
在此处输入代码

import  java.util.Scanner;
第19类{

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");
    }
}
}关于:,其中一个练习就是这样一个问题,我写了这个答案:

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

    }
}
这是伟大的,但在基督诞生之前的几年里它都不起作用(使用前公历)。如果您想让它在卑诗省使用多年,请使用以下改编:

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;
}
公共静态布尔值isLeapYear(最后整年){
最终日历cal=Calendar.getInstance();
如果(第365年;
}

你可以通过考虑将公元前5年(即公元前4年)宣布为闰年(假定为公历前一年)来验证这一点。与公元前1年(公元前1年)相同.链接到答案不能处理这种情况,而上面的修改代码可以。

如果我是讲师,我会先教单元测试。在数学和工程数学课上,通常的做法是将结果放回公式中进行检查;单元测试是让计算机为您的程序做同样的事情。我遵循Standfords编程方法学视频课程,讲师正在使用Java的艺术与科学书来教授编程方法学,而不是教授Java。我在第4章,到目前为止还没有单元测试的主题。我有点困惑,为什么1583年之前的几年是无效的?@jcw 1583是Gregorian C的第一年不同的国家在不同的年份采用了它,使得1583年和它被采用的年份之间的年份更加复杂。(一个关于它有多混乱的想法)无论如何,在创建公历之前使用公历是没有意义的。谢谢,您的回答是有意义的。使用库代码时+1。我建议在上面添加一个注释,因为400是100的倍数,您在100之前测试400,而不是原始代码。@cletus传递给cal.ge的DAY of_YEAR值在哪里tActualMaximum();该行应该是
cal.getActualMaximum(cal.DAY\u OF_YEAR);
+1表示@OlofuMark指出了这一点。但有一点小小的变化:它应该是
Calendar.getAct
java.time.Year.of(year).isLeap()
public static boolean isLeap(long year) {
        return ((year & 3) == 0) && ((year % 100) != 0 || (year % 400) == 0);
    }
import  java.util.Scanner;
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");
    }
}
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");
        }

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