son - programa de años bisiestos en java
Código de Java para calcular el año bisiesto (20)
Estoy siguiendo el libro "El arte y la ciencia de Java" y muestra cómo calcular un año bisiesto. El libro usa la biblioteca de ACM Java Task Force.
Aquí está el código que usan los libros:
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.");
}
}
Ahora, así es como calculé el año bisiesto.
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.");
}
}
}
¿Hay algún problema con mi código o debería usar el proporcionado por el libro?
EDIT :: El código anterior funciona bien. Lo que quiero preguntar es qué código es la mejor manera de calcular el año bisiesto.
Prueba del año bisiesto más eficiente:
if ((year & 3) == 0 && ((year % 25) != 0 || (year & 15) == 0))
{
/* leap year */
}
Este es un extracto de mi respuesta detallada en https://.com/a/11595914/733805
Casi siempre es incorrecto tener repetición en el software. En cualquier disciplina de ingeniería, la forma debe seguir a la función, y usted tiene tres ramas para algo que tiene dos caminos posibles: es un año bisiesto o no.
El mecanismo que tiene la prueba en una línea no tiene ese problema, pero en general sería mejor separar la prueba en una función que toma un int que representa un año y devuelve un booleano que representa si el año es año bisiesto o no . De esta forma, puede hacer algo con eso que imprima en la salida estándar en la consola y pueda probarlo más fácilmente.
En el código que se sabe que excede su presupuesto de rendimiento, es habitual organizar las pruebas para que no sean redundantes y realizar las pruebas en un orden que regrese pronto. El ejemplo de wikipedia lo hace: durante la mayoría de los años debe calcular el módulo 400.100 y 4, pero para algunos solo necesita el módulo 400 o 400 y 100. Esta es una pequeña optimización en términos de rendimiento (en el mejor de los casos, solo uno en cien) las entradas se efectúan), pero también significa que el código tiene menos repetición, y hay menos para que el programador escriba.
Como el algoritmo de los estados de wikipedia para el año bisiesto debería ser
(((year%4 == 0) && (year%100 !=0)) || (year%400==0))
Aquí hay un programa de ejemplo sobre cómo verificar el año bisiesto .
Con el curso de: https://tmc.mooc.fi , que uno de los ejercicios fue este tipo de problema, escribí esta respuesta:
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");
}
}
}
Del código fuente de GregorianCalendar 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;
}
Donde changeYear es el año en que el Calendario Juliano se convierte en el Calendario Gregoriano (1582).
El calendario juliano especifica los años bisiestos cada cuatro años, mientras que el calendario gregoriano omite los años del siglo que no son divisibles por 400.
En la documentación del Calendario Gregoriano puede encontrar más información al respecto.
Esto es lo que se me ocurrió. Hay una función adicional para verificar si el int es posterior a la fecha en que se impusieron las excepciones (año $ 100, año% 400). Antes de 1582 esas excepciones no existían.
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;
}
}
La forma más fácil de hacer el año bisiesto de Java y más claro para entender el enter code here
import java.util.Scanner;
clase 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");
}
}
}
La implementación correcta es:
public static boolean isLeapYear(int year) {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, year);
return cal.getActualMaximum(Calendar.DAY_OF_YEAR) > 365;
}
Pero si vas a reinventar esta rueda, entonces:
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;
}
}
Pseudo código de Wikipedia traducido al Java más compacto
(year % 400 == 0) || ((year % 4 == 0) && (year % 100 != 0))
Puede solicitar la clase GregorianCalendar para esto:
boolean isLeapyear = new GregorianCalendar().isLeapYear(year);
Si está usando java8:
java.time.Year.of(year).isLeap()
Implementación de Java del método anterior:
public static boolean isLeap(long year) {
return ((year & 3) == 0) && ((year % 100) != 0 || (year % 400) == 0);
}
Su código, tal como está, sin una clase adicional, no parece funcionar para java universal. Aquí hay una versión simplificada que funciona en cualquier lugar, inclinándose más hacia su 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.");
}
}
}
}
Su código, en contexto, funciona igual de bien, pero tenga en cuenta que el código del libro siempre funciona , y se prueba a fondo. No decir que el tuyo no lo es. :)
Sugiero que coloques este código en un método y crees una prueba unitaria.
public static boolean isLeapYear(int year) {
assert year >= 1583; // not valid before this date.
return ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
}
En la prueba de unidad
assertTrue(isLeapYear(2000));
assertTrue(isLeapYear(1904));
assertFalse(isLeapYear(1900));
assertFalse(isLeapYear(1901));
Me parecen iguales, aunque tenga en cuenta que esta línea en su código tiene cierta redundancia:
else if ((year % 4 == 0) && (year % 100 == 0) && (year % 400 == 0))
podría ser reemplazado por:
else if (year % 400 == 0)
Si un número es un múltiplo de 400, entonces también es automáticamente un múltiplo de 100 y 4.
editar: (¡7 años después!)
Tenga en cuenta que lo anterior asume la presencia del anterior if ((year % 4 == 0) && year % 100 != 0)
de la pregunta original.
La respuesta de Cletus debería ser la aceptada: https://.com/a/1021373/8331
(Eliminaría mi propia respuesta, pero no puedo, ya que es la aceptada)
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!");
}
}
}
}
boolean leapYear = ( ( year % 4 ) == 0 );
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!");
}
}
}
new GregorianCalendar().isLeapYear(year);
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);
}