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

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

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

有帮助吗?

解决方案

他们看起来和我一样,但请注意代码中的这一行有一些冗余:

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

可以替换为:

else if (year % 400 == 0)

如果数字是400的倍数,那么它自动也是100和4的倍数。

编辑(7年后!)

请注意,上述假设存在前面的 if((year%4 == 0)&& year%100!= 0)原来的问题!

cletus的答案应该是公认的答案: https://stackoverflow.com/a/1021373/8331

(我会删除自己的答案,但我不能,因为它已被接受)

其他提示

正确的实施是:

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

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

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

<代码> java.time.Year :: isLeap

我想添加新的 java.time 使用 Year 类和 isLeap 方法:

java.time.Year.of(year).isLeap()
new GregorianCalendar().isLeapYear(year);

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

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

最有效的闰年测试:

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

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

来自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是Julian Calendar成为阳历(1582年)的年份。

  

朱利安历法规定了每四年一次的闰年,而朱利安历法则是每四年一次   公历省略了几百年,不能被400整除。

阳历日历文档中可以找到更多相关信息。

在软件中重复几乎总是错的。在任何工程学科中,表格应该遵循功能,并且你有三个分支用于具有两个可能路径的东西 - 它是闰年或不是。

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

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

如果您使用的是java8:

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

上述方法的Java实现:

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

您可以询问 GregorianCalendar 为此类:

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

这就是我想出的。还有一个附加功能,用于检查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;
}
} 
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);    



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

        }
    }
}

维基百科应说明闰年算法

(((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闰年更清楚地理解在这里输入代码

import  java.util.Scanner;

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

}

使用以下课程: https://tmc.mooc.fi ,其中一个练习是这个问题,我写了这个答案:

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

    }
}

这个答案很棒,但在基督面前(使用一个公历的阳历)不会有多年的效果。如果你想让它适用于B.C.年,然后使用以下适应:

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年前一年)相同。链接到答案不处理这种情况,而上述改编的代码确实如此。

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!"); 
    }
    }
    }
boolean leapYear = ( ( year % 4 ) == 0 );
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top