Código Java para calcular Leap Year
-
06-07-2019 - |
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.
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 );