web-dev-qa-db-ja.com

Javaうるう年を計算するためのコード

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

コードに何か問題がありますか、または本で提供されているものを使用する必要がありますか?

編集::上記のコードはどちらも正常に機能します。うるう年を計算するには、どのコードが最良の方法かを尋ねます。

34
Ibn Saeed

これらは同じように見えますが、コードのこの行には冗長性があることに注意してください。

_else if ((year % 4 == 0) && (year % 100 == 0) && (year % 400 == 0))
_

次のものに置き換えることができます。

_else if (year % 400 == 0)
_

数値が400の倍数である場合、自動的に100と4の倍数にもなります。

edit:(7年後!)

上記は、元の質問の前のif ((year % 4 == 0) && year % 100 != 0)が存在することを前提としていることに注意してください!

cletusの答えは受け入れられるべきです: https://stackoverflow.com/a/1021373/8331

(私は自分の答えを削除しますが、受け入れられているのでできません)

13
John Carter

正しい実装は次のとおりです。

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

このコードをメソッドに入れて単体テストを作成することをお勧めします。

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));
24
Peter Lawrey

Java.time.Year::isLeap

新しい Java.timeYear クラスと isLeap メソッドでこれを行う方法:

Java.time.Year.of(year).isLeap();
16
bowmore
new GregorianCalendar().isLeapYear(year);
9
user963601

最もコンパクトなJavaに翻訳されたウィキペディアの擬似コード

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

最も効率的なうるう年のテスト:

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

これは https://stackoverflow.com/a/11595914/733805 の詳細な回答からの抜粋です。

6
Kevin P. Rice

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)になる年です。

ユリウス暦は4年ごとにうるう年を指定しますが、グレゴリオ暦は400で割り切れない世紀の年を省略します。

グレゴリオ暦のドキュメント で詳細を確認できます。

5
Felipe Andrade

Java8を使用している場合:

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

上記のメソッドのJava実装:

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

ソフトウェアで繰り返しを行うことは、ほとんど常に間違っています。エンジニアリングの分野では、フォームは機能に従う必要があります。また、2つの可能性のあるパスを持つ3つのブランチがあります。うるう年かそうでないかです。

1行でテストを行うメカニズムにはその問題はありませんが、一般的には、テストを年を表すintを取り、年がうるう年かどうかを表すブール値を返す関数に分ける方が良いでしょう。 。そうすれば、コンソールで標準出力に出力する他の操作を実行でき、より簡単にテストできます。

パフォーマンスの予算を超えることがわかっているコードでは、テストが冗長にならないように配置し、早期に返される順序でテストを実行するのが通常です。ウィキペディアの例ではこれを行います-ほとんどの場合、モジュロ400、100および4を計算する必要がありますが、モジュロ400または400および100のみを必要とするものもあります。入力に影響します)、ただし、コードの繰り返しが少なく、プログラマが入力する回数が少ないことも意味します。

3
Pete Kirkham

GregorianCalendar クラスにこれを要求できます:

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

wikipedia うるう年のアルゴリズムは

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

以下にサンプルプログラムを示します うるう年の確認方法

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

        }
    }
}
0
VirusCD

TestMyCode Programming assignment evaluator のコースでは、演習の1つがこの種の問題であったため、この答えを書きました。

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

    }
}
0
peanek

コードは、追加のクラスなしでは、ユニバーサル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.");
            }
        }
    }
}

コンテキストでは、コードは同様に機能しますが、ブックコード常に機能するであり、徹底的にテストされていることに注意してください。あなたの言うことではありません。 :)

0
Caleb Woodman

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

}

この答え は素晴らしいですが、キリストの前に何年も機能しません(予言的なグレゴリオ暦を使用)。 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年(AD 1年前)と同じです。上記の適合コードが処理するのに対し、リンクされた回答はそのケースを処理しません。

これが私が思いついたものです。 intが例外が課された日付(year $ 100、year%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
Vincent
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
user2911887