rubyでカレンダーを作ろう

rubyでカレンダーを作ってみました。

仕様

・カレンダーは日曜日から始まり土曜日で終わる。

・年と月を引数として受け取り、その月のカレンダーを返す。

僕のコード

require 'date'

TRANSLATE_MONTH = {
1 => 'January',
2 => 'Feburary',
3 => 'March',
4 => 'April',
5 => 'May',
6 => 'June',
7 => 'July',
8 => 'August',
9 => 'September',
10 => 'October',
11 => 'November',
12 => 'December'
}

WEEK_DAY = {
0 => 'Sun ',
1 => 'Mon ',
2 => 'Tue ',
3 => 'Wed ',
4 => 'Thu ',
5 => 'Fri ',
6 => 'Sat'
}

def make_calendar(year,month)
start_day = Date.new(year,month,1)
end_day = Date.new(year,month,-1)

puts "\t#{TRANSLATE_MONTH[month]} #{year}"

WEEK_DAY.each do |key,value|
if Sat?(key)
puts value
else
print value
end
end

(start_day..end_day).each do |d|
if d.day == 1
if Sat?(d.wday)
puts "#{d.day.to_s.rjust(space(d.wday))} "
else
print "#{d.day.to_s.rjust(space(d.wday))} "
end
else
if d.day >= 10
if Sat?(d.wday)
puts one_space(d.day)
else
print one_space(d.day)
end
else
if Sat?(d.wday)
puts two_space(d.day)
else
print two_space(d.day)
end
end
end
end
end

#曜日ごとに異なるスペースを渡す
def space(d)
4 * (d + 1) - 1
end

#土曜日ならtrueを返す
def Sat?(d)
d == 6
end

#一文字スペースを作る
def one_space(d)
" #{d} "
end

#2文字スペースを作る
def two_space(d)
" #{d} "
end

苦労した点

・1日は曜日に合わせて左側に空白を作らないといけないところ

・数字間を揃えたいため、1~9と10~では左側の空白の度合いを変えたところ

・上記の2つ+土曜日なら改行させるという合計3つの条件分岐があったので全体的に似たようなコードがあるように思われる。

まとめ

実はこれ作るのに午前中いっぱい使いました、、、(泣)

まだまだ改善の余地はあるだろうけど、やはり出来た時の感動は素晴らしい!!!!!

追記

皆さんのアドバイスにより改良したコードを載せます。

require 'date'

TRANSLATE_MONTH = {
1 => 'January',
2 => 'Feburary',
3 => 'March',
4 => 'April',
5 => 'May',
6 => 'June',
7 => 'July',
8 => 'August',
9 => 'September',
10 => 'October',
11 => 'November',
12 => 'December'
}

WEEK_DAY = {
0 => 'Sun ',
1 => 'Mon ',
2 => 'Tue ',
3 => 'Wed ',
4 => 'Thu ',
5 => 'Fri ',
6 => 'Sat'
}

def make_calendar(year,month)
first_day = Date.new(year,month,1)
second_day = Date.new(year,month,2)
end_day = Date.new(year,month,-1)

puts "\t#{TRANSLATE_MONTH[month]} #{year}"

WEEK_DAY.each do |key,value|
print value
puts if sat?(key)
end

print "#{'1'.rjust(space(first_day.wday))} "
puts if sat?(first_day.wday)

(second_day..end_day).each do |d|
print "%3d" % d.day
if sat?(d.wday)
puts
else
print ' '
end
end
end

#曜日ごとに異なるスペースを渡す
def space(d)
4 * (d + 1) - 1
end

#土曜日ならtrueを返す
def sat?(d)
d == 6
end

if修飾子を使い、DRYになるように意識しました。。