バイトの月報を作るのにあたって,日付のRangeを渡すと週ごとに分割するコードを書いています.つまり,
April 2008 Su Mo Tu We Th Fr Sa 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 7 8 9 10 11 12 -------------------- 13 14 15 16 17 18 19 -------------------- 20 21 22 23 24 25 26 -------------------- 27 28 29 30
こうしたい.
勉強中のRubyでコードをかいてみました.まず,テストケースのtest_gen_weeks.rb
require 'gen_weeks' require 'test/unit' require 'date' class GenWeeksTest < Test::Unit::TestCase def test_gen_week weeks = gen_week(Date.new(2008, 4, 1) .. Date.new(2008, 4, 21)) assert_equal( [ ( Date.new(2008, 4, 1) .. Date.new(2008, 4, 6) ), ( Date.new(2008, 4, 7) .. Date.new(2008, 4, 13) ), ( Date.new(2008, 4, 14) .. Date.new(2008, 4, 20) ), ( Date.new(2008, 4, 21) .. Date.new(2008, 4, 21) ) ], weeks ) end end
4月21日ような付きの途中で止まっても動くようにします.
この中で使っているgen_week関数を実装したのが,以下のコードのgen_week.rbです.
require 'date' def gen_week(range) weeks = [] week_start = week_end = range.begin loop { # 日曜日までインクリメント loop { break if week_end.wday == 0 week_end = week_end.next } # 終端に達していたら脱出 if week_end >= range.end week_end = range.end weeks.push(week_start .. week_end) break end # 一週間を登録 weeks.push(week_start .. week_end) week_start = week_end = week_end.next } return weeks end
なんかぜんぜんRubyっぽくない!きっと一発できれいに各方法があるはず.ちょっとRangeやDateのメソッドを見てきます.