私は「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の倍数にもなります。
edit:(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));
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は、ユリウス暦がグレゴリオ暦(1582)になる年です。
ユリウス暦は4年ごとにうるう年を指定しますが、グレゴリオ暦は400で割り切れない世紀の年を省略します。
グレゴリオ暦のドキュメント で詳細を確認できます。
Java8を使用している場合:
Java.time.Year.of(year).isLeap()
上記のメソッドのJava実装:
public static boolean isLeap(long year) {
return ((year & 3) == 0) && ((year % 100) != 0 || (year % 400) == 0);
}
ソフトウェアで繰り返しを行うことは、ほとんど常に間違っています。エンジニアリングの分野では、フォームは機能に従う必要があります。また、2つの可能性のあるパスを持つ3つのブランチがあります。うるう年かそうでないかです。
1行でテストを行うメカニズムにはその問題はありませんが、一般的には、テストを年を表すintを取り、年がうるう年かどうかを表すブール値を返す関数に分ける方が良いでしょう。 。そうすれば、コンソールで標準出力に出力する他の操作を実行でき、より簡単にテストできます。
パフォーマンスの予算を超えることがわかっているコードでは、テストが冗長にならないように配置し、早期に返される順序でテストを実行するのが通常です。ウィキペディアの例ではこれを行います-ほとんどの場合、モジュロ400、100および4を計算する必要がありますが、モジュロ400または400および100のみを必要とするものもあります。入力に影響します)、ただし、コードの繰り返しが少なく、プログラマが入力する回数が少ないことも意味します。
GregorianCalendar クラスにこれを要求できます:
boolean isLeapyear = new GregorianCalendar().isLeapYear(year);
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!");
}
}
}
}
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");
}
}
}
コードは、追加のクラスなしでは、ユニバーサル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うるう年でわかりやすい__を作る最も簡単な方法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;
}
}
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);
}