9

I am writing a program that is supposed to just calculate the months between 2 given dates and return the value to the program. For instance, if I have to calculate the number of months between 1 April and 30 June (which is a quarter, 3 months), and I use the following code:

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

Using this, I am still getting "2" as the number of months, whereas it is actually "3" months. This is an example of what I want. I am only calculating the number of months (i.e. from 1st of the start month t the last date of the end month) and I dont need additional analysis like days, weeks, hours, etc. How do I achieve this?

Any help would be appreciated.

Abhay Bhargav
  • 399
  • 1
  • 5
  • 15
  • 3
    Can't wait to read the answer from Jon Skeet, the Stackoverflow and Date API expert ;) – DaveFar Sep 18 '11 at 09:56
  • I believe the Yoda time answer is correct. From april 1st to (but not including) june 30th would be _almost_ 3 months. I think both dates have the same time (00:00) and thus june 30th isn't really included in the range. – extraneon Sep 18 '11 at 19:18
  • @extraneon - Thats right. The Period displayed is 2 months, 4 weeks and 1 day. – Abhay Bhargav Sep 19 '11 at 02:37

6 Answers6

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;

You need the withDaysRemoved() part to ensure that adding one to the number of months works. Otherwise two dates such as 2011-04-15 and 2011-06-14 would still result in the answer being 2

Brian Roach
  • 76,169
  • 12
  • 136
  • 161
3

Why do you expect the answer to be 3 months? The precise answer is two months and a little bit, which then results in the two months you are getting.

If you want the number of months that are “touched” by this interval, this is a completely different question. Just add 1 to the result of the difference.

Roland Illig
  • 40,703
  • 10
  • 88
  • 121
2
Months mt = Months.monthsBetween(
    start.monthOfYear().roundFloorCopy(), 
    end.monthOfYear().roundCeilingCopy()
);
javanna
  • 59,145
  • 14
  • 144
  • 125
buritos
  • 598
  • 2
  • 9
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
1

Joda algorithm counted correctly difference between this two dates. This pseudo-code will be the easiest way to explain how it works:

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

To do what you want you need to "improve" joda algorithm:

  • Count distance between two dates (use normal monthsBetween)
  • If you have specific situation: the last day of month in one date and the 1st day of month in second date, add +1 to the final result.
lukastymo
  • 26,145
  • 14
  • 53
  • 66
1

Let y1 and m1 be the year and month of the start date, and y2 and m2 be the year and month of the end date. Then the number of months between start and end, including the months of the start and end dates is

(y2 - y1) * 12 + (m2 - m1) + 1
Jiri Kriz
  • 9,192
  • 3
  • 29
  • 36