Railsからはじめるプログラミング日記

駆け出しプログラマー(主にRuby on Rails)の業務で役立ったコードをメモしていくブログです。自分だけでなく誰かの役に立てれば本望です。

たのしいRuby5版TimeクラスとDateクラス練習問題(4)

プログラミング勉強会でたのしいRubyに取り組んでいます。

第20章 TimeクラスとDateクラスの練習問題(4)がなかなか難しく、回答を調べてもあんまりヒットしなかったので私の回答をメモ程度に掲載します。

問題文

Dateクラスを使って今月の1日と月末の日付と曜日を求め、次のような形式でカレンダーを表示させてください。

f:id:oe526:20181025164517p:plain

やってみた

自力で解くのは無理でした。

ひとまず解き方を理解するのに公式の回答を見ました…なんと「万年カレンダー」の原理を使った回答でした。

…万年カレンダーってなに?って感じだったので諦めて他の回答をネット上で探すことに。

しかしあまり数はないようですね…結局「プロを目指す人のためのRuby入門」の著者、伊藤淳一さんが回答をブログに載せていたので参考にすることに。

blog.jnito.com

私的回答

会社の先輩にも手伝ってもらいながら出した回答が以下です!

require 'date'

def calender(year, month)
  first_date = Date.new(year, month, 1)
  last_date = first_date.next_month.prev_day

  puts first_date.strftime("%B %Y").center(21)
  puts "Su Mo Tu We Th Fr Sa"

  week = []
  (first_date..last_date).each do |day|
    week = [] if day.wday == 0
    week[day.wday] = day.strftime("%e")
    puts week.map{|date| date ? date : "  "}.join(" ") if day.wday == 6 or day == last_date
  end
end

calender(2018, 10)
  • first_dateで1日を取得
  • last_dateで月末の日を取得(次の月の1日前を取得)
  • 1行目に表示する年と月を中央寄せで表示(2行目の文字列の数が21文字なのでcenterの引数は21)
  • 2行目に表示する曜日は文字列でそのまま表示
  • weekという空配列を作り、1日から月末日までをeachでまわした結果をweekに入れていく
  • day.wday(土曜日)が月の最後の日のとき、weekを表示
  • day.wdayが0(日曜日にきたら)weekを初期化(これで改行を入れている)

これでうまいこと表示できました! これ以外の回答ももちろんあるはずです! Rubyって便利だなぁ。

筆者オススメ技術書