tags:

views:

2216

answers:

7

Hi all,

I have start date and end date.

I need the number of months between this two dates in java.

For eg, from date:29-01-2009 to date :02-02-2009

(It has jan date and Feb date).

It should return 2.

+1  A: 

You can use a Calendar or Joda time library for this.

In Joda time you can use the Days.daysBetween() method. You can then calculate the months difference. You can also use DateTime.getMonthOfYear() and do a subtraction (for dates in the same year).

kgiannakakis
better using Months.monthsBetween than converting to Days and then rolling back to Months ;)
nightingale2k1
I didn't know about this method. It is definitely better.
kgiannakakis
+2  A: 

Joda Time is a pretty cool library for Java Date and Time and can help you achieve what you want using Periods.

Josef
+9  A: 

I would strongly recommend Joda for this.

  1. It makes this sort of work very easy (check out Periods)
  2. It doesn't suffer from the threading issues plaguing the current date/time objects (I'm thinking of formatters, particularly)
  3. It's the basis of the new Java date/time APIs to come with Java 7 (so you're learning something that will become standard)

Note also Nick Holt's comments below re. daylight savings changes.

Brian Agnew
+1 great answer
dfa
If you can use Joda for any date related code. I'd add number 4. Joda is aware of the various changes that have occurred to datetime standards over the years, which its calculations take into account (particularly useful in Europe where daylight saving has been messed with over the years).
Nick Holt
@Nick. I didn't know that. Now noted. Thx
Brian Agnew
Joda is really good, so far is the best Date package I ever used, thanks for the recommendation.
machinegone
+2  A: 

As the rest say, if there's a library that will give you time differences in months, and you can use it, then you might as well.

Otherwise, if y1 and m1 are the year and month of the first date, and y2 and m2 are the year and month of the second, then the value you want is:

(y2 - y1) * 12 + (m2 - m1) + 1;

Note that the middle term, (m2 - m1), might be negative even though the second date is after the first one, but that's fine.

It doesn't matter whether months are taken with January=0 or January=1, and it doesn't matter whether years are AD, years since 1900, or whatever, as long as both dates are using the same basis. So for example don't mix AD and BC dates, since there wasn't a year 0 and hence BC is offset by 1 from AD.

You'd get y1 etc. either from the dates directly if they're supplied to you in a suitable form, or using a Calendar.

Steve Jessop
This solved my issue. It returns exacly what i want. thanks.
+2  A: 

using joda time would be like this (i compared how many months between today and 20/dec/2012)

import org.joda.time.DateTime ;
import org.joda.time.Months;

DateTime x = new DateTime().withDate(2009,12,20); // doomsday lol

Months d = Months.monthsBetween( new DateTime(), x);
int monthsDiff = d.getMonths();

Result: 41 months (from july 6th 2009)

should be easy ? :)

ps: you can also convert your date using SimpleDateFormat like:

Date x = new SimpleDateFormat("dd/mm/yyyy").parse("20/12/2009");
DateTime z = new DateTime(x);

If you don't want to use Joda (for whatever reason), you can convert your date to TimeStamp and then do the differences of milli seconds between both date and then calculate back to months. But I still prefer to use Joda time for the simplicity :)

nightingale2k1
If you're going to use Joda, you should use the Joda formatters as well, since the java.text stuff suffers from threading problems. I know in the above case it probably wouldn't apply, but it's a good practice :-)
Brian Agnew
hi Brian, can you give us example because I never know about that and willing to know more :) is it the substitute for SimpleDateFormat ?
nightingale2k1
A: 

Apart from using Yoda time which seems to be the the favorite suggestion I'd offer the following snippet:

public static final int getMonthsDifference(Date date1, Date date2) {
    int m1 = date1.getYear() * 12 + date1.getMonth();
    int m2 = date2.getYear() * 12 + date2.getMonth();
    return m2 - m1 + 1;
}
Roland Tepp
you mean int m1 = date1.getYear() * 12 + date1.getMonth();
Fredrick
yes, and the typo is now fixed...
Roland Tepp
A: 

I had to write this implementation, becoz I had custom defined periods, which i had to look for within two dates. Here you can define you custom period and put the logic, for calculation.

Here TimePeriod is a POJO which has start, end, period start, period End

public class Monthly extends Period {

public int getPeriodCount(String startDate, String endDate, int scalar) {
 int cnt = getPeriods(startDate, endDate, scalar).size();  
 return cnt;
}

public List getPeriods(String startDate, String endDate, int scalar) {

 ArrayList list = new ArrayList();

 Calendar startCal = CalendarUtil.getCalendar(startDate);
 Calendar endCal =  CalendarUtil.getCalendar(endDate);

 while (startCal.compareTo(endCal) <= 0) {
  TimePeriod period = new TimePeriod();
  period.setStartDate(startCal.getTime());
  period.setPeriodStartDate(getPeriodStartDate((Calendar) startCal.clone()).getTime());
  Calendar periodEndCal = getPeriodEndDate((Calendar) startCal.clone(), scalar);
  period.setEndDate(endCal.before(periodEndCal) ? endCal.getTime() : periodEndCal.getTime());
  period.setPeriodEndDate(periodEndCal.getTime());

  periodEndCal.add(Calendar.DATE, 1);
  startCal = periodEndCal;
  list.add(period);
 }

 return list;
}


private Calendar getPeriodStartDate(Calendar cal) {  
 cal.set(Calendar.DATE, cal.getActualMinimum(Calendar.DATE));  
 return cal;
}

private Calendar getPeriodEndDate(Calendar cal, int scalar) {

 while (scalar-- > 0) {
  cal.set(Calendar.DATE, cal.getActualMaximum(Calendar.DATE));
  if (scalar > 0)
   cal.add(Calendar.DATE, 1);   
 }

 return cal;
}

}

Rig Veda