我正在关注“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.");
}
}
}
我的代码有什么问题,或者我应该使用本书提供的代码吗?
编辑::以上两个代码都运行正常,我想问的是哪个代码是计算闰年的最佳方法。
答案 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)
答案 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 */
}
的详细答案的摘录
答案 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 );