用于计算闰年的Java代码

时间:2009-06-20 09:48:00

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

}

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

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

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

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

21 个答案:

答案 0 :(得分:78)

正确的实施是:

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

答案 1 :(得分: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);
}

在单元测试中

assertTrue(isLeapYear(2000));
assertTrue(isLeapYear(1904));
assertFalse(isLeapYear(1900));
assertFalse(isLeapYear(1901));

答案 2 :(得分:14)

java.time.Year::isLeap

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

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

答案 3 :(得分:13)

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

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

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

答案 4 :(得分:8)

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

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

答案 5 :(得分:8)

new GregorianCalendar().isLeapYear(year);

答案 6 :(得分:6)

最有效的闰年测试:

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

这是我在https://stackoverflow.com/a/11595914/733805

的详细答案的摘录

答案 7 :(得分: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是Julian Calendar成为阳历(1582年)的年份。

  

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

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

答案 8 :(得分:3)

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

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

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

答案 9 :(得分:3)

如果您使用的是java8:

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

上述方法的Java实现:

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

答案 10 :(得分:2)

您可以向GregorianCalendar课程询问:

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

答案 11 :(得分:0)

this answer很不错,但是在基督之前的数年里(使用可追溯的格里高利历)就无法使用。如果您希望它适用于卑诗省年,然后使用以下适应方法:

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年)发音为a年,以此来验证自己。与-1年(公元1年之前)相同。链接到答案不能处理这种情况,而上面改编的代码可以处理。

答案 12 :(得分:0)

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

    }
}

答案 13 :(得分:0)

最简单的方法来实现Java闰年,更清楚地了解enter code here

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

}

答案 14 :(得分: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.");
            }
        }
    }
}

您的代码在上下文中也可以正常工作,但请注意,图书代码始终有效,并经过彻底测试。不是说你的不是。 :)

答案 15 :(得分:0)

作为wikipedia状态,闰年的算法应为

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

以下是一个示例程序how to check for leap year

答案 16 :(得分: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!");
            }

        }
    }
}

答案 17 :(得分: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);    



}

答案 18 :(得分: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;
}
} 

答案 19 :(得分:-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!"); 
    }
    }
    }

答案 20 :(得分:-1)

boolean leapYear = ( ( year % 4 ) == 0 );