GregorianCalendar(ロジック訂正)

先日のロジック(http://d.hatena.ne.jp/tiopepe/20050204/1107526269)では,1月31日〜2月28日の例にうまく対応していなかったので訂正します。この場合,1ヶ月と1日となるので,繰り上げて2ヶ月となって欲しいところです。

  1. 年,月,日のそれぞれの成分の差(終了日−開始日)を計算する
  2. 日の差に注目して,以下の場合,月の差をインクリメントする
    • 0か正の場合
    • 負の場合でかつ,開始日の日成分(上の例では31日)が,終了日の月の最終日(同28日)よりも大きい場合
  3. 年の差に12を掛けたものに月の差を足す

ちなみにOracleSQLだと,MONTHS_BETWEEN関数が使えそうだと思って試してみました。

SQL> select trunc(months_between(to_date('02/28/05'),to_date('01/31/05'))) + 1 result from dual;

    RESULT
                  • -
2

しかし,このような月末日では想定した通り行っていますが,その少し前の日の判定がうまくありません。

SQL> select trunc(months_between(to_date('02/28/05'),to_date('01/30/05'))) + 1 result from dual;

    RESULT
                  • -
1 SQL> select trunc(months_between(to_date('02/28/05'),to_date('01/29/05'))) + 1 result from dual; RESULT
                  • -
1 SQL> select trunc(months_between(to_date('02/28/05'),to_date('01/28/05'))) + 1 result from dual; RESULT
                  • -
2

MONTHS_BETWEENの仕様のせいでしょう。LAST_DAY関数で,上で今回追加したようなロジックを入れないといけないのかもしれません。