Hatena::Grouprubyist

Ruby初心者prinyの学習帳 RSSフィード

2008-11-17

練習:Date クラス

16:18

練習:Time クラス と同じものを、今度は Date クラスを使って書く。
追加で、入力されたものが正しい暦日付けでなかったとき、プログラムが止まるのではなく、エラーを出して終了するようにする。

require 'date'

# 生年月日を入力してもらう
puts "あなたの生まれた年を西暦で入力してください。"
birth_year = gets.chomp.to_i
puts "あなたの生まれた月を入力してください。"
birth_month = gets.chomp.to_i
puts "あなたの生まれた日を入力してください。"
birth_day = gets.chomp.to_i

# 入力されたものが正しい暦日付けでなかったら、エラーを出して終了する
unless Date.valid_date?(birth_year, birth_month, birth_day)
  puts "正しい入力ではありません。"
  exit
end

your_birthday = Date.new(birth_year, birth_month, birth_day)
today = Date.today

# 生年月日を言う
puts "あなたの誕生日は #{your_birthday.strftime('%Y 年 %m 月 %d 日')} ですね。"

past_your_age = 1
past_your_birthday = your_birthday

# 過ごしてきた誕生日それぞれにおめでとうを言う
while (past_your_birthday = (past_your_birthday >> 12)) <= today
  puts "#{past_your_birthday.strftime('%Y 年 %m 月 %d 日')}#{past_your_age} 歳になったのですね。"
  puts "お誕生日おめでとう!"
  past_your_age += 1
end

つまったこと

Time クラスのときは mktime メソッドを使って日付オブジェクトを作成したけど、Date クラスのときは new メソッドを使った。そしたら、gets.chomp したものを to_i しないとエラーになった。

Time クラスのとき
puts "あなたの生まれた年を教えてください。"
birth_year = gets.chomp
puts "あなたの生まれた月を教えてください。"
birth_month = gets.chomp
puts "あなたの生まれた日を教えてください。"
birth_day = gets.chomp

your_birthday = Time.mktime(birth_year, birth_month, birth_day)
p your_birthday

実行

あなたの生まれた年を教えてください。
2000
あなたの生まれた月を教えてください。
5
あなたの生まれた日を教えてください。
20
Sat May 20 00:00:00 +0900 2000
Date クラスのとき
require 'date'

puts "あなたの生まれた年を西暦で入力してください。"
birth_year = gets.chomp
puts "あなたの生まれた月を入力してください。"
birth_month = gets.chomp
puts "あなたの生まれた日を入力してください。"
birth_day = gets.chomp

your_birthday = Date.new(birth_year, birth_month, birth_day)
p your_birthday

実行

あなたの生まれた年を西暦で入力してください。
2000
あなたの生まれた月を入力してください。
5
あなたの生まれた日を入力してください。
20
c:/ruby/lib/ruby/1.8/date.rb:596:in `<': comparison of String with 0 failed (Arg
umentError)
        from c:/ruby/lib/ruby/1.8/date.rb:596:in `valid_civil?'
        from c:/ruby/lib/ruby/1.8/date.rb:726:in `new'
        from chapter9_practice2.rb:21

まだ、エラーが出るまで何がどうなるのかわからないことが多い。

練習:Time クラス

16:08

ハッピーバースデー!  生まれた年、月、そして日を順に訊いてそこから年齢を計算します。そして、過ごしてきた誕生日それぞれに対して大きなおめでとう!をプレゼントしましょう。

http://www1.tf.chiba-u.jp/~shin/tutorial/index.rb?Chapter=09
puts "あなたの生まれた年を教えてください。"
birth_year = gets.chomp
puts "あなたの生まれた月を教えてください。"
birth_month = gets.chomp
puts "あなたの生まれた日を教えてください。"
birth_day = gets.chomp

your_birthday = Time.mktime(birth_year, birth_month, birth_day) 
today = Time.now

#生年月日から年齢を計算する
your_age = ((today.strftime('%Y%m%d').to_i - your_birthday.strftime('%Y%m%d').to_i)) / 10000

puts "あなたの誕生日は #{your_birthday.strftime('%Y 年 %m 月 %d 日')} ですね。"
puts "ということは、今は #{your_age} 歳ですね。"

##うるう年を考慮しなくていいように、年の部分だけをプラスしていく
#i = 1
#while i <= age
#  puts (birthday.strftime('%Y').to_i + i).to_s  + ' 年' +  birthday.strftime(' %m 月 %d 日') + 'に ' + i.to_s + ' 歳になったのですね。'
#  puts 'お誕生日おめでとう!'
#  i += 1
#end

#引数 birth_time に 365 日(60 * 60 * 24 * 365 秒)足した値を入れる
#うるう年の場合は、さらに 1 日(60 * 60 * 24 秒)足した値を入れる
def past_year(birth_time)
  birth_time += 60 * 60 * 24 * 365 
  year = birth_time.year
  if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))
    birth_time += 60 * 60 * 24
  end
  return birth_time
end

past_your_age = 1
past_your_birthday = your_birthday

while (past_your_birthday = past_year(past_your_birthday)) <= today
#  birthday = pastYear(birthday)
  puts "#{past_your_birthday.strftime('%Y 年 %m 月 %d 日')}#{past_your_age.to_s} 歳になったのですね。"
  puts "お誕生日おめでとう!"
  past_your_age += 1
end

holysugarholysugar2008/11/17 18:34Time.mktime も Date.new も、何を受け付けるのかちゃんとマニュアルに書いてあるので参照する癖を付けるのがいいと思いますよ。

あと、特異メソッド呼び出しを Time.mktime みたいに「.」で書く方法と Date::new みたいに「::」で書く方法を混在してるのが気になりました。もし理由がなければどちらかに統一してみては。(前者がおすすめ)

prinypriny2008/11/19 00:14コメントをありがとうございます。リファレンスマニュアルに、引数に何を指定できるのか、ちゃんと書いてありますね。はじめて使う時は、マニュアルを参照するように心がけます。

あと、「.」と「::」が混在していたのは、参照したものの書き方をまねしただけで、特に意味はありません。修正して、前者に統一しました。

prinypriny2008/11/19 00:22言葉足らずだったので補足します。「.」と「::」が混在していたのは、参考にしたもので「.」と「::」が混在して書かれていた、ということではなく、Time と Date で別のものを参考にして、それぞれの書き方をまねしたら、結果として、混在してしまった、ということです。

holysugarholysugar2008/11/19 22:03特異メソッドというかクラスメソッドですね(間違っているわけではないけど)。
と自分にselfツッコミ