43

I have start date and end date.

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

For example

  • From date: 2009-01-29
  • To date: 2009-02-02

It has one jan date and one Feb date.

It should return 2.

Lii
  • 11,553
  • 8
  • 64
  • 88

23 Answers23

43

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
  • 273,490
  • 39
  • 460
  • 699
37

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.

Community
  • 1
  • 1
Roland Tepp
  • 8,301
  • 11
  • 55
  • 73
  • 12
    Do you mean [Joda-Time](http://www.joda.org/joda-time/)? [Yoda](https://en.wikipedia.org/wiki/Yoda) time was a long time ago in a galaxy far, far away. – Basil Bourque Nov 25 '13 at 00:44
  • The + 1 on the end in the return is unnecessary. e.g. Mar 3, 2014, Mar 3, 2014 Would return a difference of 1 (when they are the same date they should return 0). I wrote some unit tests, see my code below. – Uncle Iroh Mar 26 '14 at 19:36
  • Yes, this is intentional. This will return a number of months included in the given date range. In your example, the range contains exactly one month. – Roland Tepp Mar 27 '14 at 05:52
  • 2
    Further, if you read the OP question correctly, this is exactly what was asked. – Roland Tepp Mar 27 '14 at 05:54
  • @Roland - Ah thanks for clarifying, I jumped to conclusions as to what the OP wanted. – Uncle Iroh Apr 28 '14 at 19:11
  • evene easier with 1 code line: https://stackoverflow.com/a/57074578/4211173 – Wrong Jul 17 '19 at 11:19
  • Sure, but this is essentially the same answer. Removing line breaks does not necessarily improve readability! – Roland Tepp Jul 24 '19 at 16:47
30

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.

Brian Agnew
  • 268,207
  • 37
  • 334
  • 440
  • 5
    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 Jul 06 '09 at 11:19
  • Joda is really good, so far is the best Date package I ever used, thanks for the recommendation. – machinegone Oct 10 '09 at 07:04
  • 3
    Actually, the new [JSR 310: Date and Time API](http://jcp.org/en/jsr/detail?id=310) is coming with Java 8 in 2014 (not Java 7 as stated above). Java 8 is in preview release now. – Basil Bourque Nov 25 '13 at 00:41
  • @NickHolt While I agree one should be using Joda-Time, I don't think the reason is Daylight Saving Time, not in this question. This question refers to dates without times. That means the [LocalDate](http://joda-time.sourceforge.net/apidocs/org/joda/time/LocalDate.html) class may used, without any time component, and therefore without any DST issues in play. – Basil Bourque Nov 25 '13 at 00:52
24

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.

Roland Tepp
  • 8,301
  • 11
  • 55
  • 73
  • I get "The method from(TemporalAccessor) in the type YearMonth is not applicable for the arguments (Date)". Can not see why this is upvoted. – mkurz Jun 21 '16 at 18:57
  • 1
    Yeah, Thanks for pointing out my error @mkurz, Must have slipped through somehow. Any way, I fixed these type errors now and the snippet should be okay. – Roland Tepp Jun 27 '16 at 07:37
  • 1
    This Answer ignores the crucial issue of time zone in determining a date. As written, UTC is used implicitly. Might be more appropriate to apply a `ZoneId` to the `Instant` to get a `ZonedDateTime` to be passed to `YearMonth.from`. – Basil Bourque Apr 17 '18 at 18:56
  • True, time zone is being ignored. However, the impact of time zone is negligible given that fidelity of the desired output is number of months between two date values. In a pathological case the difference may have an effect but it is highly unlikely and in the case that the difference is important enough, it would be the responsibility of a developer to makes sure that time zones line up properly. – Roland Tepp Apr 18 '18 at 06:10
  • I'm getting java.time.temporal.UnsupportedTemporalTypeException: Unsupported field: Year by using this for converting the date to Instant. The date where it fails is a current Date generated with java.util.Date() constructor. As java.util.Date class is very screwed, after dozens of years of programming in Java, I don't know the fix for this. – Mladen Adamovic Nov 07 '19 at 17:45
  • Okay, so, when I wrote this code first, I did not really check its behavior properly and it needs one more conversion to `ZonedDateTime` by calling `.atZone(ZoneOffset.UTC)` (or whatever time zone you need to make calculation in - the time zone itself does not matter in this case at all, as long as both dates are translated to the same time zone). I'm going to fix the answer. – Roland Tepp Nov 07 '19 at 20:00
17

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

}
Kuchi
  • 4,204
  • 3
  • 29
  • 37
9

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());
    }
Uncle Iroh
  • 5,748
  • 6
  • 48
  • 61
8

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
  • 10,095
  • 15
  • 70
  • 96
  • 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 Jul 06 '09 at 12:07
  • 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 Jul 06 '09 at 18:36
  • FYI, the [*Joda-Time*](http://www.joda.org/joda-time/) project is now in [maintenance mode](https://en.wikipedia.org/wiki/Maintenance_mode), with the team advising migration to the [*java.time*](http://docs.oracle.com/javase/10/docs/api/java/time/package-summary.html) classes. See [Tutorial by Oracle](https://docs.oracle.com/javase/tutorial/datetime/TOC.html). – Basil Bourque Apr 17 '18 at 18:59
3

tl;dr

ChronoUnit.MONTHS.between( 
    YearMonth.from( LocalDate.of( 2009 , 1 , 29 ) ) , 
    YearMonth.from( LocalDate.of( 2009 , 2 , 2 ) )
)

Time Zone

The Answer by Roland Tepp is close but ignores the crucial issue of time zone. Determining a month and date requires a time zone, as for any given moment the date varies around the globe by zone.

ZonedDateTime

So his example of converting java.util.Date objects to java.time.Instant objects implicitly uses UTC. Values in either of those classes is always in UTC by definition. So you need to adjust those objects into the desired/intended time zone to be able to extract a meaningful date.

ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdtStart = myJavaUtilDate1.toInstant().atZone( z );
ZonedDateTime zdtStop = myJavaUtilDate2.toInstant().atZone( z );

YearMonth

Since you want to know how many calendar months were touched by your date range rather than the number of 30-day chunks elapsed, convert to YearMonth objects.

YearMonth start = YearMonth.from( zdtStart );
YearMonth stop = YearMonth.from( zdtStop );

ChronoUnit

Calculate months between by calling on ChronoUnit enum.

long monthsBetween = ChronoUnit.MONTHS.between( start , stop );

1

Half-Open

You desired a result of 2 but we get 1 here. The reason is that in date-time work the best practice is to define spans of time by the Half-Open approach. In Half-Open, the beginning is inclusive while the ending is exclusive. I suggest you stick to this definition throughout your date-time work as doing so ultimately makes sense, eliminates confusing ambiguities, and makes your work easier to parse mentally and less error-prone. But if you insist on your definition, simply add 1 to the result assuming you have positive numbered results (meaning your spans of time go forward in time rather than backward).

LocalDate

The original Question is not clear but may require date-only values rather than date-time values. If so, use the LocalDate class. The LocalDate class represents a date-only value without time-of-day and without time zone.

LocalDate start = LocalDate.of( 2009 , 1 , 29 ) ; 
LocalDate stop = LocalDate.of( 2009 , 2 , 2 ) ;

long monthsBetween = ChronoUnit.MONTHS.between( start ,  stop );

1


About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.

Where to obtain the java.time classes?

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
2

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
  • 103,016
  • 27
  • 158
  • 194
2

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

Josef Pfleger
  • 74,165
  • 16
  • 97
  • 99
  • 1
    FYI, the [*Joda-Time*](http://www.joda.org/joda-time/) project is now in [maintenance mode](https://en.wikipedia.org/wiki/Maintenance_mode), with the team advising migration to the [*java.time*](http://docs.oracle.com/javase/10/docs/api/java/time/package-summary.html) classes. See [Tutorial by Oracle](https://docs.oracle.com/javase/tutorial/datetime/TOC.html). – Basil Bourque Apr 17 '18 at 18:59
2

It depends on your definition of a month, but this is what we use:

int iMonths = 0;

Calendar cal1 = GregorianCalendar.getInstance();
cal1.setTime(date1);

Calendar cal2 = GregorianCalendar.getInstance();
cal2.setTime(date2);

while (cal1.after(cal2)){
    cal2.add(Calendar.MONTH, 1);
    iMonths++;
}

if (cal2.get(Calendar.DAY_OF_MONTH) > cal1.get(Calendar.DAY_OF_MONTH)){
            iMonths--;
        }


return iMonths;
  • Thanks for wanting to contribute. Wonder why you are still using the outmoded `Calendar` class? Several answers here use Joda-Time (also yesterday now) and the modern `java.time`, so really, you are doing no one a favour by sharing an outdated `Calendar` solution now, sorry. – Ole V.V. May 05 '18 at 18:39
  • @OleV.V. Joda-Time is *huge* and java.time is not available on Android below API 24. – EpicPandaForce May 24 '18 at 19:42
  • 1
    Correction: `java.time` is available on lower Android API levels (below 26) though the ThreeTenABP, the Android edition of the backport. See [this questions: How to use ThreeTenABP in Android Project](https://stackoverflow.com/questions/38922754/how-to-use-threetenabp-in-android-project). – Ole V.V. May 25 '18 at 04:37
1

it is not the best anwer but you can use unixtimestamp First you find the unixtime's of the dates then eject each other

Finally you should convert the unixtime(sum) to String

Batuhan B
  • 1,835
  • 4
  • 29
  • 39
  • 1
    That would not return months difference. (Btw, this question is quite old and the options thoroughly discussed. Generally it is best to avoid resurrecting old threads unless the response contributes something significantly different over the previous answers.) – Leigh Apr 09 '12 at 22:41
1

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
  • 801
  • 2
  • 10
  • 17
1

That's because the classes Java Date and Calendar use the Month indices from 0-11

January = 0
December = 1

Is recommended to use Joda Time!

Kick Buttowski
  • 6,709
  • 13
  • 37
  • 58
lory105
  • 6,112
  • 4
  • 31
  • 40
1

Here's a solution using java.util.Calendar object:

private static Integer getMonthsBetweenDates(Date d1, Date d2) {
    Calendar todayDate = getCalendar(d1);
    Calendar pastDate = getCalendar(d2);

    int yearDiff = todayDate.get(Calendar.YEAR) - pastDate.get(Calendar.YEAR);
    if (pastDate.get(Calendar.MONTH) < 11 && pastDate.get(Calendar.DAY_OF_MONTH) < 31){ //if pastDate is smaller than 31/12
        yearDiff++;
    }

    int monthCount = 0;
    for (int year = 0 ; year < yearDiff ; year++){
        if (year == 0) {
            monthCount += 12 - pastDate.get(Calendar.MONTH);
        } else if (year == yearDiff - 1){ //last year
            if (todayDate.get(Calendar.MONTH) < pastDate.get(Calendar.MONTH)){
                monthCount += todayDate.get(Calendar.MONTH) + 1;
            } else if (todayDate.get(Calendar.MONTH) >= pastDate.get(Calendar.MONTH) && todayDate.get(Calendar.DAY_OF_MONTH) < pastDate.get(Calendar.DAY_OF_MONTH)){
                monthCount += todayDate.get(Calendar.MONTH);
            } else if (todayDate.get(Calendar.MONTH) >= pastDate.get(Calendar.MONTH) && todayDate.get(Calendar.DAY_OF_MONTH) >= pastDate.get(Calendar.DAY_OF_MONTH)){
                monthCount += todayDate.get(Calendar.MONTH) + 1;
            }
        }
        for (int months = 0 ; months < 12 ; months++){
            if (year > 0 && year < yearDiff -1){
                monthCount++;
            }
        }
    }
    return monthCount;
}
VDG
  • 11
  • 2
0

Why not calculate with full timedate

 public static Integer calculateMonthDiff(Date begining, Date end) throws Exception {

        if (begining.compareTo(end) > 0) {
            throw new Exception("Beginning date is greater than the ending date");
        }

        if (begining.compareTo(end) == 0) {
            return 0;
        }

        Calendar cEndCheckDate = Calendar.getInstance();
        cEndCheckDate.setTime(begining);
        int add = 0;
        while (true) {
            cEndCheckDate.add(Calendar.MONTH, 1);
            add++;
            if (cEndCheckDate.getTime().compareTo(end) > 0) {
                return add - 1;
            }
        }
    }
0

A full code snippet for finding the difference of months between two date is as follows:

public String getContractMonth(String contractStart, String contractEnd) {
    SimpleDateFormat dfDate = new SimpleDateFormat("yyyy-MM-dd");
    String months = "0";
    try {
        Date startDate = dfDate.parse(contractStart);
        Date endDate = dfDate.parse(contractEnd);

        Calendar startCalendar = Calendar.getInstance();
        startCalendar.setTime(startDate);
        Calendar endCalendar = Calendar.getInstance();
        endCalendar.setTime(endDate);

        int diffYear = endCalendar.get(Calendar.YEAR) - startCalendar.get(Calendar.YEAR);
        int diffMonth = diffYear * 12 + endCalendar.get(Calendar.MONTH) - startCalendar.get(Calendar.MONTH);
        months = diffMonth + "";
    } catch (ParseException e) {
        e.printStackTrace();
    } catch (java.text.ParseException e) {
        e.printStackTrace();
    }
    return months;
}
rana_sadam
  • 1,216
  • 10
  • 18
0

below logic will fetch you difference in months

(endCal.get(Calendar.YEAR)*12+endCal.get(Calendar.MONTH))-(startCal.get(Calendar.YEAR)*12+startCal.get(Calendar.MONTH))
Anoop Isaac
  • 932
  • 12
  • 15
0

you can by 30 days or by months :

public static void main(String[] args) throws IOException {

        int n = getNumbertOfMonth(LocalDate.parse("2016-08-31"),LocalDate.parse("2016-11-30"));
        System.out.println("number of month = "+n);

         n = getNumbertOfDays(LocalDate.parse("2016-08-31"),LocalDate.parse("2016-11-30"));
        System.out.println("number of days = "+n);
        System.out.println("number of 30 days = "+n/30);
    }
        static int getNumbertOfMonth(LocalDate dateDebut, LocalDate dateFin) {

        LocalDate start = dateDebut;
        LocalDate end = dateFin;
        int count = 0 ;
        List<String> lTotalDates = new ArrayList<>();
        while (!start.isAfter(end)) {
            count++;
            start =  start.plusMonths(1);
        }
        return count;
    }

    static int getNumbertOfDays(LocalDate dateDebut, LocalDate dateFin) {

        LocalDate start = dateDebut;
        LocalDate end = dateFin;
        int count = 0 ;
        List<String> lTotalDates = new ArrayList<>();
        while (!start.isAfter(end)) {
            count++;
            start =  start.plusDays(1);
        }
        return count;
    }
Azzabi Haythem
  • 2,318
  • 7
  • 26
  • 32
0
long monthsBetween = ChronoUnit.MONTHS.between(LocalDate.parse("2016-01-29").minusMonths(1),
            LocalDate.parse("2016-02-02").plusMonths(1));
  1. 2016-01-29 to 2016-01-02 = months 1
  2. 2016-02-29 to 2016-02-02 = months 1
  3. 2016-03-29 to 2016-05-02 = months 5
Prashanth Debbadwar
  • 1,047
  • 18
  • 33
  • 3
    Please add an explanation to your answer : [How do I write a good answer ?](https://stackoverflow.com/help/how-to-answer) – Mickael Feb 23 '18 at 17:02
0

Here a complete implementation for monthDiff in java without iterations. It returns the number of full month between two dates. If you want to include the number of incomplete month in the result (as in the initial question), you have to zero out the day, hours, minutes, seconds and millisecondes of the two dates before calling the method, or you could change the method to not compare days, hours, minutes etc.

import java.util.Date;
import java.util.Calendar;
...
public static int monthDiff(Date d1, Date d2) {
    int monthDiff;

    Calendar c1, c2;
    int M1, M2, y1, y2, t1, t2, h1, h2, m1, m2, s1, s2, ms1, ms2;

    c1 = Calendar.getInstance();
    c1.setTime(d1);

    c2 = Calendar.getInstance();
    c2.setTime(d2);

    M1 = c1.get(Calendar.MONTH);
    M2 = c2.get(Calendar.MONTH);
    y1 = c1.get(Calendar.YEAR);
    y2 = c2.get(Calendar.YEAR);
    t1 = c1.get(Calendar.DAY_OF_MONTH);
    t2 = c2.get(Calendar.DAY_OF_MONTH);

    if(M2 < M1) { 
        M2 += 12;
        y2--;
    }

    monthDiff = 12*(y2 - y1) + M2 - M1;

    if(t2 < t1)
        monthDiff --; // not a full month
    else if(t2 == t1) { // perhaps a full month, we have to look into the details
        h1 = c1.get(Calendar.HOUR_OF_DAY);
        h2 = c2.get(Calendar.HOUR_OF_DAY);
        if(h2 < h1)
            monthDiff--; // not a full month
        else if(h2 == h1) { // go deeper
            m1 = c1.get(Calendar.MINUTE);
            m2 = c2.get(Calendar.MINUTE);
            if(m2 < m1) // not a full month
                monthDiff--;
            else if(m2 == m1) { // look deeper
                s1 = c1.get(Calendar.SECOND);
                s2 = c2.get(Calendar.SECOND);
                if(s2 < s1)
                    monthDiff--; // on enleve l'age de mon hamster
                else if(s2 == s1) { 
                    ms1 = c1.get(Calendar.MILLISECOND);
                    ms2 = c2.get(Calendar.MILLISECOND);
                    if(ms2 < ms1)
                        monthDiff--;
                    // else // it's a full month yeah
                }
            }
        }
    }
    return monthDiff;
}
toggeli
  • 17
  • 3
  • FYI, the terribly troublesome old date-time classes such as [`java.util.Date`](https://docs.oracle.com/javase/10/docs/api/java/util/Date.html), [`java.util.Calendar`](https://docs.oracle.com/javase/10/docs/api/java/util/Calendar.html), and `java.text.SimpleDateFormat` are now [legacy](https://en.wikipedia.org/wiki/Legacy_system), supplanted by the [*java.time*](https://docs.oracle.com/javase/10/docs/api/java/time/package-summary.html) classes built into Java 8 and later. See [*Tutorial* by Oracle](https://docs.oracle.com/javase/tutorial/datetime/TOC.html). – Basil Bourque Nov 29 '18 at 17:06
  • Thanks I'am aware of this but there are still some people out there which are stuck to older JDK's. – toggeli Nov 30 '18 at 19:16
  • Most of the *java.time* functionality is available for Java 6 and Java 7 in the [*ThreeTen-Backport*](https://www.threeten.org/threetenbp/) library. So there is no need to ever again touch those bloody awful old date-time classes. – Basil Bourque Nov 30 '18 at 20:15
  • so much code for just a single math operation... https://stackoverflow.com/a/57074578/4211173 – Wrong Jul 17 '19 at 11:17
0

You can use Period class in java

    Period.between(
            firstYearMonth.atDay(1),
            secondYearMonth.atDay(1)
    ).getMonths();

This will return an integer aka month difference between 2 year month.

Kaan Ateşel
  • 363
  • 3
  • 10
-1

So many answers with long code when you can just do it with 1 line and some math:

LocalDate from = yourdate;
LocalDate to = yourotherdate;

int difference = to.getMonthValue() - from.getMonthValue()) + ((to.getYear() - from.getYear()) * 12) + 1;
Wrong
  • 1,195
  • 2
  • 14
  • 38
  • This is already in the two top-voted answers. Some of the other answers have it even simpler — one line leaving the math to a proven library method. Using `LocalDate` is a good idea for dates. – Ole V.V. Jul 17 '19 at 13:42
  • This does not add anything new to already presented answers. Removing line breaks does not make it either better or different from other similar answers. In fact it will most likely hurt readability. – Roland Tepp Jul 24 '19 at 16:49