ひと月の週数を求める(その2:月曜始まり対応)
先日、ひと月の週数を
Calendar.getActualMaximum(Calendar.WEEK_OF_MONTH);
で求める方法を書きました(→こちら)が
「月曜始まりの場合にはどうすればよいか?」というご質問を頂きました。
こんにちは、管理人イガジーです。
確かに、最近の手帳などでは「月曜始まり」が多くなっていますね。
そこで、自前で求めるメソッド(関数)を考えてみました。
ひと月の日数と、その月の1日が何曜日か、が分かれば求められそうですね。
「その月の1日が何曜日か」は、
int dow=c.get(Calendar.DAY_OF_WEEK);
で得られます。
この結果は int で、1〜7の値になります。(1=日曜,2=月曜,…)
Calendar.SUNDAY,Calendar.MONDAY, ….などのStatic Field値が
定義されているのですが、今回は端折ります。
(dow+5)%7; という計算をすると、月曜始まり時の1日の位置(オフセット値)が
得られます。具体的には、次のようになります。
日曜: dow=1 , (dow+5)%7= 6
月曜: dow=2 , (dow+5)%7= 0
火曜: dow=3 , (dow+5)%7= 1
水曜: dow=4 , (dow+5)%7= 2
…
土曜: dow=7 , (dow+5)%7= 5
このオフセット値とひと月の日数を加算して7で割り、
余りを切り上げると週数が得られます。
日曜始まりの時は、(dow+6)%7; でオフセット値が得られます。
日曜: dow=1 , (dow+6)%7= 0
月曜: dow=2 , (dow+6)%7= 1
…
土曜: dow=7 , (dow+6)%7= 6
int ws という変数に、日曜始まり(0)か、月曜始まり(1)を入れるとすると
両方まとめて(dow+6-ws)%7; という計算で済みます。
まとめると、次のようなメソッドになります。
(※ ここの month は0始まりです。0=1月、1=2月…)
int weeks(int year, int month, int ws){ // ws=1:Mondaystart 0:SundayStart
Calendar c=new GregorianCalendar(year,month,1);
int dow=c.get(Calendar.DAY_OF_WEEK);
int days=c.getActualMaximum(Calendar.DAY_OF_MONTH);
int crn=(dow+6-ws)%7;
days+=crn;
int md=days%7;
int wks=days/7;
if (md!=0) ++wks;
return wks;
}
端折るのが嫌だ(きちんとフィールド値で処理するべきだ)
と思う方は、dowをswitch/caseで処理してください。
switch (dow){
case: Calendar.SUNDAY: crn=(7-ws)%7; break;
case: Calendar.MONDAY: crn=1-ws; break;
...
case: Calendar.SATURDAY: crn=6-ws; break;
}