Pergunta

Eu estou seguindo "A arte ea ciência de Java" livro e mostra como calcular um ano bissexto. O livro usa biblioteca ACM Task Force de Java.

Aqui está o código os livros usos:

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

}

Agora, é assim que eu calculou o ano bissexto.

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

Existe errado alguma coisa com o meu código ou devo usar o fornecido pelo livro?

EDIT :: Ambos o código acima funciona bem, o que eu quero perguntar é qual código é a melhor maneira de calcular o ano bissexto.

Foi útil?

Solução

Eles têm a mesma aparência para mim, embora note que esta linha em seu código tem alguma redundância:

else if ((year % 4 == 0) && (year % 100 == 0) && (year % 400 == 0))

poderia ser substituída por:

else if (year % 400 == 0)

Se um número é um múltiplo de 400, então é automaticamente também um múltiplo de 100 e 4.

Editar: (! 7 anos mais tarde)

Por favor, note que o acima assume a presença do if ((year % 4 == 0) && year % 100 != 0) anterior da questão original!

resposta das cletus deve ser o único aceite: https://stackoverflow.com/a/1021373/8331

(eu apagar a minha própria resposta, mas eu não posso, já que é o aceito em)

Outras dicas

A implementação correta é:

public static boolean isLeapYear(int year) {
  Calendar cal = Calendar.getInstance();
  cal.set(Calendar.YEAR, year);
  return cal.getActualMaximum(Calendar.DAY_OF_YEAR) > 365;
}

Mas se você estiver indo para reinventar esta roda em seguida:

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

Eu sugiro que você colocar esse código em um método e criar um teste de unidade.

public static boolean isLeapYear(int year) {
    assert year >= 1583; // not valid before this date.
    return ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
}

No teste de unidade

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

java.time.Year::isLeap

Eu gostaria de adicionar o rel="noreferrer"> href="https://docs.oracle.com/javase/8/docs/api/java/time/package-summary.html" novo java.time <Year / a> classe e isLeap método:

java.time.Year.of(year).isLeap()
new GregorianCalendar().isLeapYear(year);

código Pseudo da Wikipedia traduzido para o mais compacto Java

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

Mais Eficiente Leap Year teste:

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

Este é um trecho do meu resposta detalhada em https://stackoverflow.com/a/11595914/733805

De GregorianCalendar código fonte de JAVA:

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

Onde changeYear é o ano do calendário Julian torna-se o calendário gregoriano (1582).

O calendário Julian especifica anos bissextos a cada quatro anos, enquanto que a anos omite calendário gregoriano do século que não são divisíveis por 400.

Na gregoriano documentação Calendário você encontram-se mais informações sobre ele.

É quase sempre errado ter repetição no software. Em qualquer disciplina de engenharia, a forma deve seguir a função, e você tem três ramos para algo que tem dois caminhos possíveis - ou é um ano bissexto ou não

.

O mecanismo que tem o teste em uma linha não tem esse problema, mas geralmente seria melhor para separar o teste em uma função que leva um int que representa um ano e retorna um booleano representando se o ano é um ano bissexto. Dessa forma, você pode fazer algo com ele outra que de impressão para a saída padrão do console, e pode mais facilmente testá-lo.

No código que é conhecido por exceder o seu orçamento de desempenho, é habitual para organizar os testes para que eles não são redundantes e realizar os testes em uma ordem que retorna cedo. O exemplo wikipedia faz isso - para a maioria dos anos você tem que calcular modulo 400.100 e 4, mas para alguns que você só precisa módulo 400 ou 400 e 100. Isto é uma pequena otimização em termos de desempenho (na melhor das hipóteses, apenas um em cada cem entradas são efetuadas), mas também significa que o código tem menos repetição, e há menos para o programador para digitar.

Se você estiver usando java8:

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

implementação Java do método acima:

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

Você pode pedir ao GregorianCalendar classe para isso:

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

Isto é o que eu vim acima com. Há uma função adicional para verificar para ver se o int é passado a data em que foram aplicadas as exceções (ano US $ 100, no ano% 400). Antes de 1582 essas exceções não estavam por perto.

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



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

        }
    }
}

Como wikipedia afirma algoritmo para o ano bissexto deve ser

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

Aqui está um programa de exemplo como verificar para ano bissexto .

O seu código, como ela é, sem uma classe adicional, não parece trabalho para java universal. Aqui está uma versão simplificada que funciona em qualquer lugar, se inclinando mais para o seu código.

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

O seu código, no contexto, funciona tão bem, mas note que o código livro sempre funciona , e é testado exaustivamente. Não quer dizer que o seu não é. :)

maneira mais fácil ta fazer java ano bissexto e mais claro para understandenter code here

import  java.util.Scanner;

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

}

Com o curso de: https://tmc.mooc.fi , que um dos exercícios era esse tipo de problema, eu escrevi esta resposta:

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

    }
}

esta resposta é grande, mas não vai funcionar durante anos antes de Cristo (usando um calendário gregoriano proleptic). Se você quer que ele funcione para aC anos, em seguida, usar a seguinte adaptação:

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

Você pode verificar isso por si mesmo, considerando que no ano -5 (ou seja, 4 aC) deve ser pronunciado como um ano bissexto assumindo um calendário gregoriano proleptic. Mesmo com ano -1 (um ano antes de 1 AD). O ligado a resposta não lidar com esse caso ao passo que o código acima adaptada faz.

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!"); 
    }
    }
    }
boolean leapYear = ( ( year % 4 ) == 0 );
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top