bluedwarfの日記: Rubyでカレンダー 6
日記 by
bluedwarf
カレンダーをHTMLとして出力するコードをRubyで書こうとしたのだが、Dateを使ったら意外にコンパクトなコードで、しかもそれなりにわかりやすいコードが書けたので晒してみる。
Dateを使わなければ、閏年の判定から曜日の判定までコーディングして、たくさんの条件分岐ができたけれども、これだとほとんど条件分岐しなくて済むので、見やすい見やすい。
-----
# 指定された月のカレンダーをHTMLのテーブルとして返す
def html_calendar(year,month)
ret = "<table border>\n"
ret << "<tr><td>日</td><td>月</td><td>火</td><td>水</td><td>木</td><td>金</td><td>土</td></tr>\n"
ret << "<tr>"
current = Date.new(year,month,1)
unless current.wday == 0 then
for x in 1..current.wday do
ret << "<td></td>"
end
end
while current.month == month do
if current.wday == 0 then
ret << "</tr>\n"
ret << "<tr>"
end
ret << "<td>#{current.day}</td>"
current = current.next
end
unless current.wday == 0 then
for x in current.wday..6 do
ret << "<td></td>"
end
end
ret << "</tr>\n"
ret << "<table>"
return ret
end
-----
Rubyってコードを書く人のくせがはっきりとでるので、突っ込まれるのがとても恐いのですが。
# それでも突っ込み歓迎。
Dateを使わなければ、閏年の判定から曜日の判定までコーディングして、たくさんの条件分岐ができたけれども、これだとほとんど条件分岐しなくて済むので、見やすい見やすい。
-----
# 指定された月のカレンダーをHTMLのテーブルとして返す
def html_calendar(year,month)
ret = "<table border>\n"
ret << "<tr><td>日</td><td>月</td><td>火</td><td>水</td><td>木</td><td>金</td><td>土</td></tr>\n"
ret << "<tr>"
current = Date.new(year,month,1)
unless current.wday == 0 then
for x in 1..current.wday do
ret << "<td></td>"
end
end
while current.month == month do
if current.wday == 0 then
ret << "</tr>\n"
ret << "<tr>"
end
ret << "<td>#{current.day}</td>"
current = current.next
end
unless current.wday == 0 then
for x in current.wday..6 do
ret << "<td></td>"
end
end
ret << "</tr>\n"
ret << "<table>"
return ret
end
-----
Rubyってコードを書く人のくせがはっきりとでるので、突っ込まれるのがとても恐いのですが。
# それでも突っ込み歓迎。
短くしてみる (スコア:1)
require 'date'
def html_calender(year, month)
ret = '<table border><tr><td>Sun<td>Mon<td>Tue<td>Wed<td>Thu<td>Fri<td>Sat'
(first = Date.new(year, month)).wday == 0 or ret << '<tr>'
ret << ('<td>' * first.wday)
first.upto((first >> 1) - 1) do |day|
day.wday != 0 or ret << '<tr>'
ret << "<td>#{day.day}"
end
ret << '</table>'
end
# 凝りすぎたかなぁ
Re:短くしてみる (スコア:1)
# w3mから「こんなのHTMLじゃない!」とかきても、私は知りませんが(笑)
-----
ret ' * first.wday)
-----
この部分はかなり関心しました。
// Give me chocolates!
Rubyらしさを盛り込むと・・・ (スコア:1)
require 'date'
def html_calender(year, month)
date = Date.new(year, month, 1)
week = (date+1).cweek
array = Array.new(6).map {|a| a = Array.new(7) }
while date.month == month
array[(date+1).cweek-week][date.wday] = date.day
date = date.next
end
array.delete_if {|a| a.compact.empty? }
array.unshift(%w(日 月 火 水 木 金 土))
table = "<table border>"
array.each {|w|
table << "<tr><td>" + w.join("</td><td>") + "</td>\n"
}
table << "</table>"
end
Re:Rubyらしさを盛り込むと・・・ (スコア:1)
C:\>diff -u cal_tsyk.rb.prev cal_tsyk.rb
--- cal_tsyk.rb.prev 2003-06-02 02:05:04.000000000 +0900
+++ cal_tsyk.rb 2003-06-02 01:58:14.000000000 +0900
@@ -5,14 +5,18 @@
week = (date+1).cweek
array = Array.new(6).map {|a| a = Array.new(7) }
while date.month == month
- array[(date+1).cweek-week][date.wday] = date.day
+ cw = (date+1).cweek - week
+ cw += 52 if cw < 0
+ array[cw][date.wday] = date.day
date = date.next
end
array.delete_if {|a| a.compact.empty? }
array.unshift(%w(日 月 火 水 木 金 土))
table = "<table border>"
array.each {|w|
- table << "<tr><td>" + w.join("</td><td>") + "</td>\n"
+ table << "<tr><td>" + w.join("</td><td>") + "</td></tr>\n"
}
table << "</table>"
end
<http://www.ruby-lang.org/ja/man-1.6/index.cgi?cmd=view;name=Date>
リファレンスマニュアルには "cweek 暦週を返します (1-53)" って書いてあるのに…
C:\>irb
irb(main):001:0> require 'date'
=> true
irb(main):002:0> Date.new(2003, 12, 28).cweek
=> 52
irb(main):003:0> Date.new(2003, 12, 29).cweek
=> 1
irb(main):004:0>
Re:Rubyらしさを盛り込むと・・・ (スコア:1)
翌年の1月1日が金曜日の場合だけ、その年には「53週目」が存在するらしい。
こんな定義は始めて知りました。
C:\>irb
irb(main):001:0> require 'date'
=> true
irb(main):002:0> Date.new(1981, 12, 31).cweek
=> 53
irb(main):003:0> Date.new(1987, 12, 31).cweek
=> 53
irb(main):004:0> Date.new(1992, 12, 31).cweek
=> 53
irb(main):005:0> Date.new(1998, 12, 31).cweek
=> 53
irb(main):006:0> Date.new(2009, 12, 31).cweek
=> 53
irb(main):007:0> [nagaokaut.ac.jp]
Re:Rubyらしさを盛り込むと・・・ (スコア:1)
// Give me chocolates!