2011-09-18 11 views
9

Sto scrivendo un programma che dovrebbe calcolare solo i mesi tra 2 date date e restituire il valore al programma. Per esempio, se devo calcolare il numero di mesi tra il 1 aprile e il 30 giugno (che è un quarto, 3 mesi), e ho utilizzare il seguente codice:Come calcolare la differenza SOLO in mesi utilizzando l'API Joda di 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(); 

Usando questo, ancora sto ottenendo " 2 "come il numero di mesi, mentre in realtà è" 3 "mesi. Questo è un esempio di ciò che voglio. Sto solo calcolando il numero di mesi (cioè dal 1 ° del mese di inizio t l'ultima data del mese di fine) e non ho bisogno di ulteriori analisi come giorni, settimane, ore, ecc. Come posso raggiungere questo obiettivo?

Qualsiasi aiuto sarebbe apprezzato.

+3

Non vedo l'ora di leggere la risposta da Jon Skeet, lo StackOverflow e data Esperto API;) – DaveFar

+0

Credo che la risposta temporale Yoda sia corretta. Dal 1 ° aprile al 30 giugno, escluso il 30 giugno, dureranno quasi tre mesi. Penso che entrambe le date abbiano la stessa ora (00:00) e quindi il 30 giugno non è realmente incluso nell'intervallo. – extraneon

+0

@extraneon - Proprio così. Il periodo visualizzato è di 2 mesi, 4 settimane e 1 giorno. –

risposta

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; 

È necessario la parte withDaysRemoved() al fine di garantire che l'aggiunta di uno al numero di mesi funziona. In caso contrario, due date come 2011-04-15 e 2011-06-14 risulterebbero comunque nella risposta 2

+0

Sembra funzionare correttamente. Farò qualche altro test e controllo –

+0

Questo non funziona. Ad esempio, fallisce per 2015-06-10 e 2015-07-01 ("mesi" finisce con 1 invece di 2). La soluzione corretta può essere trovata qui: http://stackoverflow.com/a/1086432/1369016 – Tiago

3

Perché si aspetta che la risposta sia 3 months? La risposta esatta è due mesi e un po ', che quindi risulta nello due mesi che si ottiene.

Se si desidera il numero di mesi "toccati" da questo intervallo, questa è una domanda completamente diversa. Basta aggiungere 1 al risultato della differenza.

+0

Il problema è che a seconda del giorno previsto, aggiungere uno al mese potrebbe non funzionare. –

+0

Non intendevo aggiungere un mese a una data, ma aggiungere 1 alla variabile 'monthDiff' nella domanda. –

+1

Lo so. Se le date fossero 2011-04-15 e 2011-06-14, ciò fallirebbe perché getMonths() restituirebbe 1. –

1

Algoritmo di Joda contato correttamente la differenza tra queste due date. Questo pseudo-codice sarà il modo più semplice per spiegare come funziona:

// (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 

di fare ciò che si vuole è necessario "migliorare" algoritmo Joda:

  • distanza Conte tra due date (uso normale mesi tra)
  • Se si dispone di una situazione specifica: l'ultimo giorno del mese in una data e il 1 ° giorno del mese in seconda data, aggiungere +1 al risultato finale.
1

Let y1 e m1 essere l'anno e il mese della data di inizio, e y2 e m2 essere l'anno e il mese della data di fine. Poi il numero di mesi tra inizio e la fine, compresi i mesi dalle date di inizio e fine è

(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 
Problemi correlati