Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Date month difference

Tags:

java

date

People also ask

How do you calculate months in Java?

Once you have the LocalDate, you can use Months. monthsBetween() and Years. yearsBetween() method to calcualte the number of months and years between two dates in Java. LocalDate jamesBirthDay = new LocalDate(1955, 5, 19); LocalDate now = new LocalDate(2015, 7, 30); int monthsBetween = Months.

How do you calculate the difference between two dates in Java?

getTime() – d1. getTime(). Use date-time mathematical formula to find the difference between two dates. It returns the years, days, hours, minutes, and seconds between the two specifies dates.

Can you subtract dates in Java?

The minusDays() method of LocalDate class in Java is used to subtract the number of specified day from this LocalDate and return a copy of LocalDate. For example, 2019-01-01 minus one day would result in 2018-12-31.


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.


Apart from using Joda 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;
}

EDIT: Since Java 8, there is a more standard way of calculating same difference. See my alternative answer using JSR-310 api instead.


I would strongly recommend Joda-Time (and as of Java 8, the Java Time apis) 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.


Now that JSR-310 has been included in the SDK of Java 8 and above, here's a more standard way of getting months difference of two date values:

public static final long getMonthsDifference(Date date1, Date date2) {
    YearMonth m1 = YearMonth.from(date1.toInstant().atZone(ZoneOffset.UTC));
    YearMonth m2 = YearMonth.from(date2.toInstant().atZone(ZoneOffset.UTC));

    return m1.until(m2, ChronoUnit.MONTHS) + 1;
}

This has a benefit of clearly spelling out the precision of the calculation and it is very easy to understand what is the intent of the calculation.


Java 8 solution:

@Test
public void monthBetween() {

    LocalDate d1 = LocalDate.of(2013, Month.APRIL, 1);
    LocalDate d2 = LocalDate.of(2014, Month.APRIL, 1);

    long monthBetween = ChronoUnit.MONTHS.between(d1, d2);

    assertEquals(12, monthBetween);

}

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 :)


Based on the above suggested answers I rolled my own which I added to my existing DateUtils class:

    public static Integer differenceInMonths(Date beginningDate, Date endingDate) {
        if (beginningDate == null || endingDate == null) {
            return 0;
        }
        Calendar cal1 = new GregorianCalendar();
        cal1.setTime(beginningDate);
        Calendar cal2 = new GregorianCalendar();
        cal2.setTime(endingDate);
        return differenceInMonths(cal1, cal2);
    }

    private static Integer differenceInMonths(Calendar beginningDate, Calendar endingDate) {
        if (beginningDate == null || endingDate == null) {
            return 0;
        }
        int m1 = beginningDate.get(Calendar.YEAR) * 12 + beginningDate.get(Calendar.MONTH);
        int m2 = endingDate.get(Calendar.YEAR) * 12 + endingDate.get(Calendar.MONTH);
        return m2 - m1;
    }

And the associatiated unit tests:

    public void testDifferenceInMonths() throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
        assertEquals(12, DateUtils.differenceInMonths(sdf.parse("2014/03/22"), sdf.parse("2015/03/22")).intValue());

        assertEquals(11, DateUtils.differenceInMonths(sdf.parse("2014/01/01"), sdf.parse("2014/12/25")).intValue());

        assertEquals(88, DateUtils.differenceInMonths(sdf.parse("2014/03/22"), sdf.parse("2021/07/05")).intValue());

        assertEquals(6, DateUtils.differenceInMonths(sdf.parse("2014/01/22"), sdf.parse("2014/07/22")).intValue());
    }