Java Date month difference

2019-01-04 14:20发布

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.

标签: java date
21条回答
闹够了就滚
2楼-- · 2019-01-04 14:40

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

查看更多
姐就是有狂的资本
3楼-- · 2019-01-04 14:41

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

查看更多
混吃等死
4楼-- · 2019-01-04 14:42

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;
            }
        }
    }
查看更多
淡お忘
5楼-- · 2019-01-04 14:43

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());
    }
查看更多
我想做一个坏孩纸
6楼-- · 2019-01-04 14:44

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;
}
查看更多
等我变得足够好
7楼-- · 2019-01-04 14:46

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.

查看更多
登录 后发表回答