日付と曜日
2009/07/23
今週1週間の日付と曜日を表示するプログラムを書きなさい。ただし、週は日曜日から始まるものとします。
日付と曜日の表示形式は自由に選択して構いません。今日が2009年7月23日とすると、例えば次のように表示されれば結構です。
07/19 (Sun) 07/20 (Mon) 07/21 (Tue) 07/22 (Wed) 07/23 (Thu) 07/24 (Fri) 07/25 (Sat)
なお、プログラムの作成にあたり、Rubyの標準ライブラリを利用することができます。
--
黒田努
解答と解説
問題文中にある「Rubyの標準ライブラリ」が何を指すかがポイントです。
RUBY初心者の小林さんの解答は、次の通りです。
def OutputDate( time ) print time.strftime("%m") + "/" + time.strftime("%d") +" (" +time.strftime("%a") + ")\n" end day_time = 60*60*24 t = Time.new t = t - ( day_time*t.wday ) for i in 0..6 add_time = day_time OutputDate( t + ( add_time*i ) ) end
組み込みクラスのTime
を使用した実装です。
ローカル変数t
に現在時刻をセットし、t.wday
日分の秒数を引いて、t
にセットし直しています。wday
は、日曜日を0、月曜日を1…とした「曜日」を示す整数ですから、変数t
は今週の日曜日のどこかの時刻を指しています。そして、0から6までの整数をi
に順にセットしつつ、変数t
からi
日分が経過した時刻をメソッドOutput
で表示しています。
機能的には問題ないのですが、いくつか修正したい点があります。
1つは、strftime
メソッドの使い方。引数に指定する文字列にはスラッシュ(/)等の記号を含めることができるので、次のように簡潔に書けます。
def OutputDate( time ) print time.strftime("%m/%d (%a)\n") end
それから、一時変数add_time
が余分です。
for i in 0..6 OutputDate( t + ( day_time*i ) ) end
最も気になったのは、ローカル変数t
の役割が途中で変化していることと、一日のどこかの時刻を指していることです。コードを追いかけていけば計算が正しいことは分かりますが、ぱっと見て理解できるほどではありません。
日付を扱うならDate
クラスを利用すべきでしょう。
次のコードはMTGさんの解答です。
this_day = Date.today this_sunday = this_day - this_day.wday 0.upto(6) do |i| day = this_sunday + i puts day.strftime("%m/%d (%a)") end
実は、私が模範解答として示そうと思っていたのとほとんど同じでした。
しかし、惜しい!
Date
クラスは標準クラスであって、組み込みクラスではないので、require
する必要があります。多分、メールに添付する際に手違いがあったのでしょう。
というわけで、模範解答は次の通り。
require 'date' this_sunday = Date.today - Date.today.wday 0.upto(6) do |i| day = this_sunday + i puts day.strftime("%m/%d (%a)") end
「解答と解説」掲載後に、MTGさんからメールがあり、ご本人の環境ではrequire 'date'
の行がなくてもエラーにならないとのご指摘をいただきました。どのような条件下でエラーにならないのかまだ判明していませんが、「通常はrequire
する必要がある」と訂正いたします。ご存じの方がいらっしゃいましたら教えてください。
また、同じくMTGさんより、Date.today
と Date.today.wday
の間で日付が変わる可能性はないのかと質問をいただきました。つまり、this_sunday
が土曜日になる可能性はないのか、という指摘です。実験としてTime.now.usec - Time.now.usec
というコードを実行してみると、確かに-1
とか-2
の値が返ってきます。MTGさんのコードの方が正確です。訂正いたします。
上記の訂正を掲載した後に、river125さんからメールが届き、環境変数 RUBYOPT
に -rrubygems
または -rauto_gem
という値がセットされていると、require 'date'
が不要になると教えていただきました。One-click Ruby Installer で Windows に Ruby をインストールした場合や、Gentoo Linux を使用している場合などが該当するようです。情報提供、ありがとうございました。