この投稿のコードがあまりにも長かったので自分なりに作ってみました。
実装ルール(要件)はこんな感じ。
- 任意の年月を指定して1ヶ月分のカレンダーを出力する
- 週のはじまりの曜日を指定できる(日曜・月曜以外でも指定可能…用途があるかは置いといて)
- 週単位で、前月・次月の日付も表示する
Groovy の処理系は java.util.Calendar を拡張しているのでこれを使わない手はありません。Java の資産を活用してこその Groovy です。
MyCalendar.groovy
def DAY_OF_WEEKS = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
def getMonth = { year, month, firstDay=Calendar.SUNDAY ->
def cal = Calendar.instance // Java の Calendar.getInstance() 相当
cal.set(year, month-1, 1) // month-1 は Calendar クラスの仕様による
cal.setFirstDayOfWeek(firstDay) // 週のはじまる曜日をセット
// その月に何週あるかを取得
def weeks = cal.getActualMaximum( Calendar.WEEK_OF_MONTH )
// カレンダーのヘッダ部分(不要なら def result = [] とかしておく)
def result = [["","$year/$month","(starts","with",DAY_OF_WEEKS[firstDay-1]+")"]]
result.add( (0..6).collect{ DAY_OF_WEEKS[(firstDay-1+it)%7] } )
// 週のはじまる曜日まで日付をさかのぼる
while( cal.get(Calendar.DAY_OF_WEEK) != firstDay ){ cal = cal.previous() }
// 各週の日付を出力
weeks.times { result.add( (0..6).collect{ (cal++).get( Calendar.DAY_OF_MONTH ) as String } ) }
return result
}
// こっちは表示用なので適当に
def printMonth = { month ->
month.each{ week ->
week.each{ print it.padLeft(3) + " " }
println ""
}
println ""
}
def one = getMonth(2013,11,Calendar.MONDAY)
printMonth(one)
one = getMonth(2013,9,Calendar.MONDAY)
printMonth(one)
one = getMonth(2013,6,Calendar.MONDAY)
printMonth(one)
one = getMonth(2013,11)
printMonth(one)
one = getMonth(2013,9)
printMonth(one)
one = getMonth(2013,6)
printMonth(one)
one = getMonth(2013,6,Calendar.SATURDAY)
printMonth(one)
one = getMonth(2013,6,Calendar.TUESDAY)
printMonth(one)
出力はこんな感じになります。
2013/11 (starts with Mon)
Mon Tue Wed Thu Fri Sat Sun
28 29 30 31 1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 1
2013/9 (starts with Mon)
Mon Tue Wed Thu Fri Sat Sun
26 27 28 29 30 31 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 1 2 3 4 5 6
2013/6 (starts with Mon)
Mon Tue Wed Thu Fri Sat Sun
27 28 29 30 31 1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
2013/11 (starts with Sun)
Sun Mon Tue Wed Thu Fri Sat
27 28 29 30 31 1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
2013/9 (starts with Sun)
Sun Mon Tue Wed Thu Fri Sat
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 1 2 3 4 5
2013/6 (starts with Sun)
Sun Mon Tue Wed Thu Fri Sat
26 27 28 29 30 31 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 1 2 3 4 5 6
2013/6 (starts with Sat)
Sat Sun Mon Tue Wed Thu Fri
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 1 2 3 4 5
2013/6 (starts with Tue)
Tue Wed Thu Fri Sat Sun Mon
28 29 30 31 1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 1
format()を使えば曜日の表記を自前で持つ必要すら無いんですが、個々の日付に曜日を出すわけではないのでそこはなんとなくサボりました。
WebアプリケーションではDatePicker系のJavascriptライブラリが充実しているので、あまり使い道はないかもしれませんね。