2009-06-20 81 views
28

我关注“Java的艺术与科学”一书,它展示了如何计算闰年。本书使用ACM Java任务组的库。用于计算闰年的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."); 
     } 
    } 
} 

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

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

+1

最好的代码将使用受信任的库,而不是。 Cletus使用Calendar类的建议是一个很好的例子。 – 2009-06-20 12:52:30

+0

如果使用常规Java库,你是正确的。但在我的课程中,我正在使用ACM的Java Task Force的库。 http://www-cs-faculty.stanford.edu/~eroberts/jtf/ – 2009-06-20 13:06:32

+1

这里是类似的线程。 http://stackoverflow.com/questions/7395699/calculate-leap-year-in-java/7395759#7395759 – CharithJ 2011-09-13 01:41:20

回答

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)

在任何情况下,使用库代码是一个更好的解决方案,克莱的答案应该被接受的一个:https://stackoverflow.com/a/1021373/8331

+1

更正,4,而不是4! :) – Sev 2009-06-20 09:57:48

+0

为了避免(!)感叹号和非运算符之间的混淆,修正了这个错误;) – 2009-06-20 10:00:31

20

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

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

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

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

在已知超出其性能预算的代码中,通常安排测试,以便它们不是多余的,并按早期返回的顺序执行测试。维基百科的例子是这样做的 - 大多数年份你必须计算模400,100和4,但少数你只需要模400或400和100.这是一个性能方面的小优化(最多只有百分之一输入是有效的),但这也意味着代码的重复性较低,程序员输入的内容也较少。

66

正确的实现是:

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; 
    } 
} 
6
从维基百科

伪代码翻译成最紧凑的Java

(year % 400 == 0) || ((year % 4 == 0) && (year % 100 != 0)) 
-1
boolean leapYear = ((year % 4) == 0); 
-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!"); 
    } 
    } 
    } 
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; 
} 
} 
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);  



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

     } 
    } 
} 
8
new GregorianCalendar().isLeapYear(year); 
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."); 
      } 
     } 
    } 
} 

您的代码,在上下文中,效果一样好,但要注意的是书码始终工作,并经过全面的测试。不要说你的不是。 :)

9

java.time.Year::isLeap

我想要添加具有Year类和isLeap方法这样做的新java.time方式:

java.time.Year.of(year).isLeap() 
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日历成为公历(1582)的一年。

儒略历指定闰年每四年,而 公历省略世纪年份不属于整除400

在关于它的Gregorian Calendar documentation你可以找到更多信息。

1

你可以问GregorianCalendar类这样的:

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

如果您正在使用java8:

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

Java实现上述方法:

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

最简单的方法TA使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"); 
    } 
} 

}