Calculate month difference in Joda Time

16,038

Solution 1

Months.monthsBetween(
     start.withDayOfMonth(1),
     end.withDayOfMonth(1)).getMonths()

Solution 2

This is pretty similar to Bozho's solution:

  public static YearMonth toYearMonth(LocalDate localDate) {
    return new YearMonth(localDate.getYear(), localDate.getMonthOfYear());
  }

  public static int monthSwitches(LocalDate date1,LocalDate date2) {
    return Months.monthsBetween(toYearMonth(date1),toYearMonth(date2)).getMonths();
  }

Solution 3

This is the solution I came up with when commenting on Bozho

int handleAllowance(LocalDate today) {

    int allowance = membership.allowance();
    if (allowance == 0) return 0;

    // calculate month difference
    int allowanceMonths = Months.monthsBetween(lastAllowanceUpdate.withDayOfMonth(1), today.withDayOfMonth(1)).getMonths();

    // if update was last month or earlier
    if (allowanceMonths > 0) {

        // ...and if today is on or past update day
        int updateDay = Math.min(allowanceDay, today.dayOfMonth().getMaximumValue());
        if (today.getDayOfMonth() >= updateDay) {

            // give credits (multiply with months in the rare case this process consecutively fails to run for 2 months or more)
            final int totalAllowance = allowance * allowanceMonths;
            giveCredits(totalAllowance);

            // update day
            lastAllowanceUpdate = lastAllowanceUpdate.plusMonths(allowanceMonths);

            // return the allowance given
            return totalAllowance;

        }

    }

    return 0;
}
Share:
16,038

Related videos on Youtube

Bart van Heukelom
Author by

Bart van Heukelom

Professional software developer, online games, full stack but mostly backend. Electronics tinkerer. Maker. Freelance. See LinkedIn for more details. My UUID is 96940759-b98b-4673-b573-6aa6e38272c0

Updated on July 22, 2022

Comments

  • Bart van Heukelom
    Bart van Heukelom almost 2 years

    At the 4th line of code (ignore whitespace & comments) and beyond I'm calculating the month difference between 2 dates. This works, but looks a bit hacky. Is there a better way?

    int handleAllowance(LocalDate today) {
    
        int allowance = membership.allowance();
        if (allowance == 0) return 0;
    
        // if update was last month (or earlier)
        int months = today.monthOfYear().getMaximumValue() - today.monthOfYear().getMinimumValue(); // yeah, 12, but just to be 100% correct :-)
        int curMonth = (today.getYear()               * months) + today.              getMonthOfYear();
        int updMonth = (lastAllowanceUpdate.getYear() * months) + lastAllowanceUpdate.getMonthOfYear();
        if (curMonth > updMonth) {
    
            // ...and if today is on or past update day
            int updateDay = Math.min(allowanceDay, today.dayOfMonth().getMaximumValue());
            if (today.getDayOfMonth() >= updateDay) {
    
                // number of months to give allowance (in the rare case this process fails to run for 2 months or more)
                int allowanceMonths = curMonth - updMonth;
    
                // give credits
                final int totalAllowance = allowance * allowanceMonths;
                giveCredits(totalAllowance);
    
                // update day
                lastAllowanceUpdate = lastAllowanceUpdate.plusMonths(allowanceMonths);
    
                // return the allowance given
                return totalAllowance;
    
            }
    
        }
    
        return 0;
    }
    
  • Bart van Heukelom
    Bart van Heukelom almost 13 years
    Won't that return 0 if date1 is January 31 and date2 is February 1? I basically need to discard day information and then calculate the difference...oh, wait, that's how I could do it. :p
  • Bart van Heukelom
    Bart van Heukelom almost 13 years
    I posted my solution as answer
  • zeddarn
    zeddarn over 9 years
    I used this and gets this org.joda.time.IllegalFieldValueException: Value 0 for dayOfMonth must be in the range [1,28]
  • Matt Leonowicz
    Matt Leonowicz over 8 years
    @zeddarn Yes. In Yoda Time months start from 1 (days also), as opposed to Calendar 0. Remember to add +1 if you pass from Calendar to Yoda
  • Lucas Oliveira
    Lucas Oliveira about 8 years
    This solution works for scenarios like "29/01/2016" and "01/02/2016"!