2011-07-27 52 views
9

在第四行代碼(忽略空白&評論)以後,我計算了兩個日期之間的月差。這工作,但看起來有點哈克。有沒有更好的辦法?計算Joda時間的月差

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; 
} 
+0

一個問題,雖然題外話:是'allowance'constan?如果不是這樣,'final int totalAllowance = allowance * allowanceMonths;'可能爲'allowanceMonths> 1'產生不同的結果,而運行整個部分'allowanceMonths'次。 – Thomas

+0

定義常量。它的價值取決於用戶的訂閱類型,該用戶的訂閱類型可以在2個月的某個時間段內改變。但它不會以任何其他方式進行更改。所以我想如果這個過程無法運行2個月,並且用戶決定在它再次運行的前一天升級訂閱,他會得到比預期更多的津貼。這很好,但這不是一個致命的錯誤,而且極不可能'allowanceMonths'永遠不會真的> 1 –

+0

隨着常數的增加,我的意思是「兩次運行之間的值是否可以變化,並且結果取決於信用還是類似」?既然你似乎有一個不斷的津貼(除非用戶改變訂閱類型),這可能是好的。你也可以每個月都這樣做,並讓每個月的訂閱類型更加準確。 – Thomas

回答

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

如果date1是1月31日,而date2是2月1日,那不會返回0嗎?我基本上需要放棄一天的信息,然後計算差異......哦,等等,這就是我能做到的。 :p –

+0

是的,只是'date.withDayOfMonth(0)' – Bozho

+0

我發佈了我的解決方案作爲答案 –

1

這是我來了個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; 
} 
2

這是非常相似Bozho的解決方案進行評論時用的解決方案:

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(); 
    } 
+0

此解決方案適用於「29/01/2016」和「 2016" 年1月2日! –