Calcular días entre dos fechas con Java
Quiero un programa Java que calcule los días entre dos fechas.
- Escriba la primera fecha (notación alemana; con espacios en blanco: "dd mm aaaa")
- Escriba la segunda fecha.
- El programa debería calcular el número de días entre las dos fechas.
¿Cómo puedo incluir los años bisiestos y el verano?
Mi código:
import java.util.Calendar;
import java.util.Date;
import java.util.Scanner;
public class NewDateDifference {
public static void main(String[] args) {
System.out.print("Insert first date: ");
Scanner s = new Scanner(System.in);
String[] eingabe1 = new String[3];
while (s.hasNext()) {
int i = 0;
insert1[i] = s.next();
if (!s.hasNext()) {
s.close();
break;
}
i++;
}
System.out.print("Insert second date: ");
Scanner t = new Scanner(System.in);
String[] insert2 = new String[3];
while (t.hasNext()) {
int i = 0;
insert2[i] = t.next();
if (!t.hasNext()) {
t.close();
break;
}
i++;
}
Calendar cal = Calendar.getInstance();
cal.set(Calendar.DAY_OF_MONTH, Integer.parseInt(insert1[0]));
cal.set(Calendar.MONTH, Integer.parseInt(insert1[1]));
cal.set(Calendar.YEAR, Integer.parseInt(insert1[2]));
Date firstDate = cal.getTime();
cal.set(Calendar.DAY_OF_MONTH, Integer.parseInt(insert2[0]));
cal.set(Calendar.MONTH, Integer.parseInt(insert2[1]));
cal.set(Calendar.YEAR, Integer.parseInt(insert2[2]));
Date secondDate = cal.getTime();
long diff = secondDate.getTime() - firstDate.getTime();
System.out.println ("Days: " + diff / 1000 / 60 / 60 / 24);
}
}
ACTUALIZACIÓN: La respuesta original de 2013 ahora está desactualizada porque algunas de las clases han sido reemplazadas. La nueva forma de hacerlo es utilizando las nuevas java.time
clases.
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd MM yyyy");
String inputString1 = "23 01 1997";
String inputString2 = "27 04 1997";
try {
LocalDateTime date1 = LocalDate.parse(inputString1, dtf);
LocalDateTime date2 = LocalDate.parse(inputString2, dtf);
long daysBetween = Duration.between(date1, date2).toDays();
System.out.println ("Days: " + daysBetween);
} catch (ParseException e) {
e.printStackTrace();
}
Tenga en cuenta que esta solución proporcionará la cantidad de días reales de 24 horas, no la cantidad de días calendario. Para este último, utilice
long daysBetween = ChronoUnit.DAYS.between(date1, date2)
Respuesta original (obsoleta a partir de Java 8)
Estás realizando algunas conversiones con tus Strings que no son necesarias. Hay una SimpleDateFormat
clase para ello; prueba esto:
SimpleDateFormat myFormat = new SimpleDateFormat("dd MM yyyy");
String inputString1 = "23 01 1997";
String inputString2 = "27 04 1997";
try {
Date date1 = myFormat.parse(inputString1);
Date date2 = myFormat.parse(inputString2);
long diff = date2.getTime() - date1.getTime();
System.out.println ("Days: " + TimeUnit.DAYS.convert(diff, TimeUnit.MILLISECONDS));
} catch (ParseException e) {
e.printStackTrace();
}
EDITAR: Dado que ha habido algunas discusiones sobre la exactitud de este código: de hecho, se ocupa de los años bisiestos. Sin embargo, la TimeUnit.DAYS.convert
función pierde precisión ya que los milisegundos se convierten a días (consulte el documento vinculado para obtener más información). Si esto es un problema, diff
también se puede convertir a mano:
float days = (diff / (1000*60*60*24));
Tenga en cuenta que este es un float
valor, no necesariamente un int
.
La forma más sencilla:
public static long getDifferenceDays(Date d1, Date d2) {
long diff = d2.getTime() - d1.getTime();
return TimeUnit.DAYS.convert(diff, TimeUnit.MILLISECONDS);
}
En Java 8, puedes lograr esto usando LocalDate
y DateTimeFormatter
. Del Javadoc de LocalDate
:
LocalDate es un objeto de fecha y hora inmutable que representa una fecha, a menudo vista como año-mes-día.
Y el patrón se puede construir usando DateTimeFormatter
. Aquí está el Javadoc y los caracteres de patrón relevantes que utilicé:
Símbolo - Significado - Presentación - Ejemplos
y - año de la era - año - 2004; 04
M/L - mes del año - número/texto - 7; 07; Jul; Julio; j
d - día del mes - número - 10
Aquí está el ejemplo:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
public class Java8DateExample {
public static void main(String[] args) throws IOException {
final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd MM yyyy");
final BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
final String firstInput = reader.readLine();
final String secondInput = reader.readLine();
final LocalDate firstDate = LocalDate.parse(firstInput, formatter);
final LocalDate secondDate = LocalDate.parse(secondInput, formatter);
final long days = ChronoUnit.DAYS.between(firstDate, secondDate);
System.out.println("Days between: " + days);
}
}
Ejemplo de entrada/salida con el último más reciente:
23 01 1997
27 04 1997
Days between: 94
Con el primero más reciente:
27 04 1997
23 01 1997
Days between: -94
Bueno, podrías hacerlo como método de una forma más sencilla:
public static long betweenDates(Date firstDate, Date secondDate) throws IOException
{
return ChronoUnit.DAYS.between(firstDate.toInstant(), secondDate.toInstant());
}
La mayoría de las respuestas nos causaron problemas cuando llegó el horario de verano. Aquí está nuestra solución funcional para todas las fechas, sin utilizar JodaTime. Utiliza objetos de calendario:
public static int daysBetween(Calendar day1, Calendar day2){
Calendar dayOne = (Calendar) day1.clone(),
dayTwo = (Calendar) day2.clone();
if (dayOne.get(Calendar.YEAR) == dayTwo.get(Calendar.YEAR)) {
return Math.abs(dayOne.get(Calendar.DAY_OF_YEAR) - dayTwo.get(Calendar.DAY_OF_YEAR));
} else {
if (dayTwo.get(Calendar.YEAR) > dayOne.get(Calendar.YEAR)) {
//swap them
Calendar temp = dayOne;
dayOne = dayTwo;
dayTwo = temp;
}
int extraDays = 0;
int dayOneOriginalYearDays = dayOne.get(Calendar.DAY_OF_YEAR);
while (dayOne.get(Calendar.YEAR) > dayTwo.get(Calendar.YEAR)) {
dayOne.add(Calendar.YEAR, -1);
// getActualMaximum() important for leap years
extraDays += dayOne.getActualMaximum(Calendar.DAY_OF_YEAR);
}
return extraDays - dayTwo.get(Calendar.DAY_OF_YEAR) + dayOneOriginalYearDays ;
}
}
La mejor manera, y se convierte en una cadena como beneficio adicional;)
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
//Dates to compare
String CurrentDate= "09/24/2015";
String FinalDate= "09/26/2015";
Date date1;
Date date2;
SimpleDateFormat dates = new SimpleDateFormat("MM/dd/yyyy");
//Setting dates
date1 = dates.parse(CurrentDate);
date2 = dates.parse(FinalDate);
//Comparing dates
long difference = Math.abs(date1.getTime() - date2.getTime());
long differenceDates = difference / (24 * 60 * 60 * 1000);
//Convert long to String
String dayDifference = Long.toString(differenceDates);
Log.e("HERE","HERE: " + dayDifference);
}
catch (Exception exception) {
Log.e("DIDN'T WORK", "exception " + exception);
}
}