2011-09-18 9 views
9

Estoy escribiendo un programa que se supone que solo calcula los meses entre 2 fechas dadas y devuelve el valor al programa. Por ejemplo, si tengo que calcular el número de meses entre el 1 de abril y el 30 de junio (que es un cuarto, 3 meses), y utilizar el siguiente código:Cómo calcular la diferencia ÚNICAMENTE en meses utilizando la API Joda de Java

DateTime start = new DateTime().withDate(2011, 4, 1); 
    DateTime end = new DateTime().withDate(2011, 6, 30); 

    Months mt = Months.monthsBetween(start, end); 
    int monthDiff = mt.getMonths(); 

El uso de este, todavía estoy recibiendo " 2 "como el número de meses, mientras que en realidad es" 3 "meses. Este es un ejemplo de lo que quiero. Solo estoy calculando el número de meses (es decir, desde el 1 ° del mes de inicio hasta la última fecha del mes final) y no necesito análisis adicionales como días, semanas, horas, etc. ¿Cómo lo logro?

Cualquier ayuda sería apreciada.

+3

No puedo esperar para leer la respuesta de Jon Skeet, el Stackoverflow y fecha Experto en API;) – DaveFar

+0

Creo que la respuesta del tiempo Yoda es correcta. Del 1 de abril al (pero sin incluir) el 30 de junio sería de casi 3 meses. Creo que ambas fechas tienen el mismo horario (00:00) y, por lo tanto, el 30 de junio no está realmente incluido en el rango. – extraneon

+0

@extraneon - Eso es correcto. El período mostrado es de 2 meses, 4 semanas y 1 día. –

Respuesta

9
DateTime start = new DateTime().withDate(2011, 4, 1); 
DateTime end = new DateTime().withDate(2011, 6, 30); 
Period p = new Period(start, end, PeriodType.months().withDaysRemoved()); 
int months = p.getMonths() + 1; 

Usted necesita la parte withDaysRemoved() para asegurar que la adición de uno al número de meses funciona. De lo contrario, dos fechas como 2011-04-15 y 2011-06-14 seguirán dando como resultado que la respuesta sea 2

+0

Esto parece estar funcionando bien. Haré algunas pruebas más y comprobar –

+0

Esto no está funcionando. Por ejemplo, falla para 2015-06-10 y 2015-07-01 ("meses" termina con 1 en lugar de 2). La solución correcta se puede encontrar aquí: http://stackoverflow.com/a/1086432/1369016 – Tiago

3

¿Por qué esperas que la respuesta sea 3 months? La respuesta exacta es dos meses y un poco, que luego da como resultado el dos meses que está recibiendo.

Si desea el número de meses que están "tocados" en este intervalo, esta es una pregunta completamente diferente. Simplemente agregue 1 al resultado de la diferencia.

+0

El problema es que dependiendo del día proporcionado, agregar uno al mes podría no funcionar. –

+0

No quise agregar un mes a una fecha, sino agregar 1 a la variable 'monthDiff' en la pregunta. –

+1

Lo sé. Si las fechas fueran 2011-04-15 y 2011-06-14, eso no funcionaría porque getMonths() devolvería 1. –

1

El algoritmo Joda contó correctamente la diferencia entre estas dos fechas. Este pseudo-código será la forma más fácil de explicar cómo funciona:

// (1) 
monthsBetween(2011.6.14, 2011.4.15) = 1 
monthsBetween(2011.6.15, 2011.4.15) = 2 
// (2) 
monthsBetween(2011.6.30, 2011.4.1) = 2 
monthsBetween(2011.7.1, 2011.4.1) = 3 

para hacer lo que desea es necesario "mejorar" algoritmo de joda:

  • distancia Conde entre dos fechas (uso normal mesesEntre)
  • Si tiene una situación específica: el último día del mes en una fecha y el primer día del mes en la segunda fecha, agregue +1 al resultado final.
1

Vamos y1 y m1 sea el año y el mes de la fecha de inicio, y y2 y m2 sea el año y el mes de la fecha de finalización. A continuación, el número de meses entre inicio y final, incluyendo los meses de las fechas de inicio y fin es

(y2 - y1) * 12 + (m2 - m1) + 1 
2
Months mt = Months.monthsBetween(
    start.monthOfYear().roundFloorCopy(), 
    end.monthOfYear().roundCeilingCopy() 
); 
1
DateTime start = new DateTime().withDate(2011, 4, 1); 
     DateTime end = new DateTime().withDate(2011, 2, 1); 
     Period p = new Period(start, end, PeriodType.months().withDaysRemoved()); 
     int months = p.getMonths(); 
     System.out.println(months); 


wrong output in this case 
Cuestiones relacionadas