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;
}
Related videos on Youtube
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, 2022Comments
-
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 almost 13 yearsWon'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 almost 13 yearsI posted my solution as answer
-
zeddarn over 9 yearsI used this and gets this
org.joda.time.IllegalFieldValueException: Value 0 for dayOfMonth must be in the range [1,28]
-
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 fromCalendar
to Yoda -
Lucas Oliveira about 8 yearsThis solution works for scenarios like "29/01/2016" and "01/02/2016"!