2011-09-18 1 views
9

Piszę program, który ma po prostu obliczyć miesiące między 2 podanymi datami i zwrócić wartość do programu. Na przykład, jeśli muszę obliczyć liczbę miesięcy między 1 kwietnia a 30 czerwca (który jest dzielnica, 3 miesiące) i używam następujący kod:Jak obliczyć różnicę TYLKO w miesiącach używając Jody API Jody

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(); 

Korzystanie z tego, ja wciąż się " 2 "jako liczba miesięcy, podczas gdy faktycznie jest to" 3 "miesiące. To jest przykład tego, czego chcę. Obliczam tylko liczbę miesięcy (tj. Od 1 dnia miesiąca początkowego do ostatniej daty miesiąca końcowego) i nie potrzebuję dodatkowych analiz, takich jak dni, tygodnie, godziny itp. Jak to osiągnąć?

Każda pomoc zostanie doceniona.

+3

nie mogę się doczekać, aby przeczytać odpowiedź od Jon Skeet, na Stackoverflow i data Ekspert API;) – DaveFar

+0

Wierzę, że odpowiedź czasu Yoda jest poprawna. Od 1 kwietnia do (ale nie wliczając) 30 czerwca będzie to 3 miesiące. Myślę, że obie daty mają ten sam czas (00:00), a więc 30 czerwca tak naprawdę nie jest w tym zakresie. – extraneon

+0

@extraneon - To prawda. Wyświetlany okres to 2 miesiące, 4 tygodnie i 1 dzień. –

Odpowiedz

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; 

Musisz withDaysRemoved() udział w celu zapewnienia, że ​​dodanie jednego do liczby miesięcy działa. W przeciwnym razie dwa terminy takie jak 2011-04-15 i 2011-06-14 nadal prowadzić w odpowiedzi będącego 2

+0

Wydaje się, że działa poprawnie. Zrobię więcej testów i sprawdzę –

+0

To nie działa. Na przykład nie uda się na 2015-06-10 i 2015-07-01 ("miesiące" kończą się 1 zamiast 2). Prawidłowe rozwiązanie można znaleźć tutaj: http://stackoverflow.com/a/1086432/1369016 – Tiago

3

Dlaczego oczekujesz odpowiedzi na 3 months? Dokładna odpowiedź to dwa miesiące i trochę, co powoduje, że otrzymujesz dwa miesiące.

Jeśli chcesz liczbę miesięcy, które są "dotknięte" przez ten przedział, jest to zupełnie inne pytanie. Po prostu dodaj 1 do wyniku różnicy.

+0

Problem polega na tym, że w zależności od podanego dnia dodanie jednego na miesiąc może nie działać. –

+0

Nie chciałem dodawać miesiąca do daty, ale dodawać 1 do zmiennej 'monthDiff' w pytaniu. –

+1

Wiem. Jeśli daty to 2011-04-15 i 2011-06-14, to może się nie powieść, ponieważ funkcja getMonths() zwróci wartość 1. –

1

Joda algorytm poprawnie liczone różnica między tym dwoma datami. Ten pseudo-kod będzie najprostszym sposobem, aby wyjaśnić, jak to działa:

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

Aby zrobić to, co chcesz trzeba „poprawić” algorytm Joda:

  • odległość Hrabia między dwiema datami (użyj normalne miesiąceBetween)
  • Jeśli masz konkretną sytuację: ostatni dzień miesiąca w jednej dacie i pierwszy dzień miesiąca w drugiej dacie, dodaj +1 do końcowego wyniku.
1

Niech y1 i m1 jest rok i miesiąc od daty rozpoczęcia, i y2 i m2 jest rok i miesiąc od daty zakończenia. Następnie liczbę miesięcy między początku i na końcu, w tym miesięcy od daty rozpoczęcia i zakończenia jest

(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