今日は6月29日です。29日というのがミソです。
#ここでもう分かったという方も多いかと思います。
Javaで、2月の日数が28日か29日かを取るために、CalendarクラスのgetActualMaximumメソッドを使っています。これはその月の最大日(1月なら31、4月なら30)を返します。2月の場合、うるう年か否かによって、29か28が返ります。
このメソッドを使って2月の末日を取得しようと、まずCalendarクラスのインスタンスを取得します。
Calendar theDay = Calendar.getInstance();
次に、2011年2月を設定します。
theDay.set(Calendar.YEAR, 2011);
theDay.set(Calendar.MONTH, Calendar.FEBRUARY);
- ここで問題が入っています。
そして、2月の末日を取得します。
int maxDate = theDay.getActualMaximum(Calendar.DATE);
なぜか31という値を取得しました。
あれっと思い、2012年2月を設定してみたら、
theDay.set(Calendar.YEAR, 2012) theDay.set(Calendar.MONTH, Calendar.FEBRUARY); int maxDate = theDay.getActualMaximum(Calendar.DATE);
29という値を取得しました。あれっ
Calendarクラスのset
CalendarクラスのインスタンスをgetInstance()で取得すると、現在時刻が入っています。
2011年6月29日にプログラムを実行すると、2011年6月29日が入ります。
次に、setメソッドで2月を設定すると、2011年2月29日になろうとするのですが、2011年には2月は28日しかないので、非厳密モード(デフォルトの振る舞い)では2011年3月1日となります。
この後、getActualMaximumメソッドを呼ぶと、3月の末日である31が返されます。
一方、setメソッドで2012年を設定し、続いて2月を設定すると、2012年はうるう年で2月が29日なので、2月29日は有効な日であるため、そのまま設定されます。この後、getActualMaximumメソッドを呼ぶと、2月の末日である29が返ります。
対策
- Calendarのsetメソッドを呼ぶ前に、clearメソッドを呼んでおく
- Calendarのsetメソッドには、年月日を一度に設定するオーバーロードがあるので、それを呼ぶ
があります。
theDay.set(2011, 1, 1); int maxDate = theDay.getActualMaximum(Calendar.DATE);