2010-08-19 15 views
39

Mi corazón está sangrando internamente después de tener que ir tan profundo como para restar dos fechas para calcular el lapso en el número de días:¿Cómo restar fechas en Java?

GregorianCalendar c1 = new GregorianCalendar(); 
    GregorianCalendar c2 = new GregorianCalendar(); 
    c1.set(2000, 1, 1); 
    c2.set(2010,1, 1); 
    long span = c2.getTimeInMillis() - c1.getTimeInMillis(); 
    GregorianCalendar c3 = new GregorianCalendar(); 
    c3.setTimeInMillis(span); 
    long numberOfMSInADay = 1000*60*60*24; 
    System.out.println(c3.getTimeInMillis()/numberOfMSInADay); //3653 

donde es sólo 2 líneas de código en .NET, o cualquier lenguaje moderno que el nombre .

¿Es esto atroz de Java? ¿O hay un método oculto que debería saber?

En lugar de utilizar GregorianCalendar, ¿está bien utilizar Date class in util? Si es así, ¿debería estar atento a cosas sutiles como el año 1970?

Gracias

+1

¿por qué se utiliza c3? Afaik podría dejar al menos las dos líneas para c3;) – ZeissS

Respuesta

49

Es de hecho uno de los mayores fracasos épicos en la API estándar de Java. Tenga un poco de paciencia, luego obtendrá su solución en el sabor de la nueva API de fecha y hora especificada por JSR 310/ThreeTen que (lo más probable) se incluirá en el próximo Java 8.

Hasta entonces, puede salirse con JodaTime.

DateTime dt1 = new DateTime(2000, 1, 1, 0, 0, 0, 0); 
DateTime dt2 = new DateTime(2010, 1, 1, 0, 0, 0, 0); 
int days = Days.daysBetween(dt1, dt2).getDays(); 

Su creador, Stephen Colebourne, es por la forma en que el hombre detrás de JSR 310, por lo que un aspecto muy similar.

+3

Tengo un proyecto pequeño y lo necesito solo en unos pocos lugares. Al volver de .NET, estoy un poco furioso y frustrado con Java. Gracias por la confirmación, sin embargo. – Haoest

+1

También podría crear un método de utilidad y ocultarlo muy lejos en las profundidades de su código para que no le moleste directamente la fea API de Calendar;) – BalusC

+0

¿Ha visto el JSR 310 alguna vez el día? –

3

Si maneja las fechas, es una buena idea consultar la biblioteca de tiempos de joda para obtener un modelo de manipulación de fechas más racional.

http://joda-time.sourceforge.net/

3

Bien puede quitar la tercera instancia calendario.

GregorianCalendar c1 = new GregorianCalendar(); 
GregorianCalendar c2 = new GregorianCalendar(); 
c1.set(2000, 1, 1); 
c2.set(2010,1, 1); 
c2.add(GregorianCalendar.MILLISECOND, -1 * c1.getTimeInMillis()); 
+3

No creo que GregorianCalendar sea inmutable, por lo que si debería volver a usar c2 más tarde, me gustaría tener el valor como se definió inicialmente. – Haoest

18

se puede utilizar el siguiente enfoque:

SimpleDateFormat formater=new SimpleDateFormat("yyyy-MM-dd"); 

long d1=formater.parse("2001-1-1").getTime(); 
long d2=formater.parse("2001-1-2").getTime(); 

System.out.println(Math.abs((d1-d2)/(1000*60*60*24))); 
0

Aquí está el enfoque básico,

DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); 

Date beginDate = dateFormat.parse("2013-11-29"); 
Date endDate = dateFormat.parse("2013-12-4"); 

Calendar beginCalendar = Calendar.getInstance(); 
beginCalendar.setTime(beginDate); 

Calendar endCalendar = Calendar.getInstance(); 
endCalendar.setTime(endDate); 

hay forma sencilla de ponerlo en práctica. Podemos usar el método Calendar.add con loop. Los días menos entre BeginDate y endDate y el código implementado de la siguiente manera,

int minusDays = 0; 
while (true) { 
    minusDays++; 

    // Day increasing by 1 
    beginCalendar.add(Calendar.DAY_OF_MONTH, 1); 

    if (dateFormat.format(beginCalendar.getTime()). 
      equals(dateFormat.format(endCalendar).getTime())) { 
    break; 
    } 
} 
System.out.println("The subtraction between two days is " + (minusDays + 1));** 
+0

Excelente uso de la palabra "substractación" :) –