質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Q&A

解決済

4回答

1828閲覧

ruby 子供の学年を判断するプログラム

Nish

総合スコア14

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

0グッド

0クリップ

投稿2020/04/04 00:16

Rubyで誕生日の生年月日から現在の学年を判断するプログラムを作りたいと思っています。
現在下記のプログラムですと誕生日を迎えた時点で学年が上がってしまいます。4月1日の時点で
学年が上がるようにしたいのですが、どのように修正したらいいか伺えないでしょうか。
何卒宜しくお願い申し上げます。

ruby

require "date"

puts "西暦何年にお子さんは生まれましたか"
by = gets.to_i
puts "何月にお子さんは生まれましたか"
bm = gets.to_i
puts "何日に生まれましたか"
bd = gets.to_i

birthday =Time.mktime(by,bm,bd)
age = (Date.today.strftime('%Y%m%d').to_i - birthday.strftime('%Y%m%d').to_i) / 10000

case age

when 0
puts "学校にはまだいけません。"
when 1
puts "学校にはまだいけません。"
when 2
puts "学校にはまだいけません。"
when 3
puts "幼稚園の年少です。"
when 4
puts "幼稚園の年中です。"
when 5
puts "幼稚園の年長です"
when 6
puts "小学校一年生です。"
when 7
puts "小学校二年生です。"
when 8
puts "小学校三年生です。"
when 9
puts "小学校四年生です。"
when 10
puts "小学校五年生です。"
when 11
puts "小学校六年生です。"
when 12
puts "中学校一年生です。"
when 13
puts "中学校二年生です。"
when 14
puts "中学校三年生です。"
when 15
puts "高校一年生です。"
when 16
puts "高校二年生です。"
when 17
puts "高校三年生です。"
when 18
puts "大学一年生です。"
when 19
puts "大学二年生です。"
when 20
puts "大学三年生です。"
when 21
puts "大学四年生です。"
else
puts "社会人です。"
end

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

今日が 3 月までなら去年、4 月以降なら今年の 4/1 を基準日として年齢を考えればいいので、こんな感じでしょうか。

diff

1 birthday =Time.mktime(by,bm,bd) 2-age = (Date.today.strftime('%Y%m%d').to_i - birthday.strftime('%Y%m%d').to_i) / 10000 3+today = Date.today 4+toDate = Time.mktime(today.year - (today.month < 4 ? 1 : 0), 4, 1) 5+age = (toDate.strftime('%Y%m%d').to_i - birthday.strftime('%Y%m%d').to_i) / 10000

実行結果(なお、一学年は4月2日生まれから翌年の4月1日生まれの児童生徒までで構成される ことにご注意ください。)

$ ruby schoolYear.rb 西暦何年にお子さんは生まれましたか 2000 何月にお子さんは生まれましたか 1 何日に生まれましたか 1 大学三年生です。 $ ruby schoolYear.rb 西暦何年にお子さんは生まれましたか 2000 何月にお子さんは生まれましたか 4 何日に生まれましたか 1 大学三年生です。 $ ruby schoolYear.rb 西暦何年にお子さんは生まれましたか 2000 何月にお子さんは生まれましたか 4 何日に生まれましたか 2 大学二年生です。 $ ruby schoolYear.rb 西暦何年にお子さんは生まれましたか 2000 何月にお子さんは生まれましたか 12 何日に生まれましたか 31 大学二年生です。

ちなみに、一点バグが残ってますが、これはご自分でなんとかしてください。

$ ruby schoolYear.rb 西暦何年にお子さんは生まれましたか 2020 何月にお子さんは生まれましたか 4 何日に生まれましたか 3 社会人です。

また、余計なお世話ですが、年齢通りに進学しない人もいますし、大学に行かない人も、逆に大学を出てすぐに社会人にならない人もいますので、使いみちによってはその辺の配慮も必要かと存じます。


せっかく書いたので、テストコードを載せておきます。

ruby

1# test_sample.rb 2require 'test/unit' 3require 'date' 4 5class Sample 6 def self.age(birthday, today) 7 (today.strftime('%Y%m%d').to_i - birthday.strftime('%Y%m%d').to_i) / 10000 8 end 9 10 def self.schoolYear(birthday, today = Date.today) 11 toDate = Time.mktime(today.year - (today.month < 4 ? 1 : 0), 4, 1) 12 (toDate.strftime('%Y%m%d').to_i - birthday.strftime('%Y%m%d').to_i) / 10000 13 end 14end 15 16class TestSample < Test::Unit::TestCase 17 def test_age 18 assert_equal 20, Sample.age(Time.mktime(2000, 1, 1), Time.mktime(2020, 1, 1)) 19 20 assert_equal 19, Sample.age(Time.mktime(2000, 1, 2), Time.mktime(2020, 1, 1)) 21 assert_equal 20, Sample.age(Time.mktime(2000, 1, 2), Time.mktime(2020, 1, 2)) 22 assert_equal 20, Sample.age(Time.mktime(2000, 1, 2), Time.mktime(2020, 1, 3)) 23 24 assert_equal 19, Sample.age(Time.mktime(2000, 2, 28), Time.mktime(2020, 2, 27)) 25 assert_equal 20, Sample.age(Time.mktime(2000, 2, 28), Time.mktime(2020, 2, 28)) 26 assert_equal 20, Sample.age(Time.mktime(2000, 2, 28), Time.mktime(2020, 2, 29)) 27 assert_equal 20, Sample.age(Time.mktime(2000, 2, 28), Time.mktime(2020, 3, 1)) 28 29 assert_equal 19, Sample.age(Time.mktime(2000, 2, 29), Time.mktime(2020, 2, 28)) 30 assert_equal 20, Sample.age(Time.mktime(2000, 2, 29), Time.mktime(2020, 2, 29)) 31 assert_equal 20, Sample.age(Time.mktime(2000, 2, 29), Time.mktime(2020, 3, 1)) 32 33 assert_equal 18, Sample.age(Time.mktime(2001, 2, 28), Time.mktime(2020, 2, 27)) 34 assert_equal 19, Sample.age(Time.mktime(2001, 2, 28), Time.mktime(2020, 2, 28)) 35 assert_equal 19, Sample.age(Time.mktime(2001, 2, 28), Time.mktime(2020, 2, 29)) 36 assert_equal 19, Sample.age(Time.mktime(2001, 2, 28), Time.mktime(2020, 3, 1)) 37 38 assert_equal 20, Sample.age(Time.mktime(2000, 2, 29), Time.mktime(2021, 2, 27)) 39 assert_equal 20, Sample.age(Time.mktime(2000, 2, 29), Time.mktime(2021, 2, 28)) 40 assert_equal 21, Sample.age(Time.mktime(2000, 2, 29), Time.mktime(2021, 3, 1)) 41 end 42 43 def test_schoolYear 44 assert_equal 20, Sample.schoolYear(Time.mktime(2000, 1, 1)) 45 assert_equal 20, Sample.schoolYear(Time.mktime(2000, 2, 29)) 46 assert_equal 20, Sample.schoolYear(Time.mktime(2000, 3, 31)) 47 assert_equal 20, Sample.schoolYear(Time.mktime(2000, 4, 1)) 48 assert_equal 19, Sample.schoolYear(Time.mktime(2000, 4, 2)) 49 assert_equal 19, Sample.schoolYear(Time.mktime(2000, 5, 1)) 50 assert_equal 19, Sample.schoolYear(Time.mktime(2000, 12, 31)) 51 52 assert_equal 19, Sample.schoolYear(Time.mktime(2000, 1, 1), Date.new(2020, 1, 1)) 53 assert_equal 19, Sample.schoolYear(Time.mktime(2000, 1, 1), Date.new(2020, 3, 31)) 54 assert_equal 20, Sample.schoolYear(Time.mktime(2000, 1, 1), Date.new(2020, 4, 1)) 55 assert_equal 20, Sample.schoolYear(Time.mktime(2000, 1, 1), Date.new(2020, 4, 2)) 56 assert_equal 20, Sample.schoolYear(Time.mktime(2000, 1, 1), Date.new(2020, 12, 31)) 57 58 assert_equal 19, Sample.schoolYear(Time.mktime(2000, 4, 1), Date.new(2020, 1, 1)) 59 assert_equal 19, Sample.schoolYear(Time.mktime(2000, 4, 1), Date.new(2020, 3, 31)) 60 assert_equal 20, Sample.schoolYear(Time.mktime(2000, 4, 1), Date.new(2020, 4, 1)) 61 assert_equal 20, Sample.schoolYear(Time.mktime(2000, 4, 1), Date.new(2020, 4, 2)) 62 assert_equal 20, Sample.schoolYear(Time.mktime(2000, 4, 1), Date.new(2020, 12, 31)) 63 64 assert_equal 18, Sample.schoolYear(Time.mktime(2000, 4, 2), Date.new(2020, 1, 1)) 65 assert_equal 18, Sample.schoolYear(Time.mktime(2000, 4, 2), Date.new(2020, 3, 31)) 66 assert_equal 19, Sample.schoolYear(Time.mktime(2000, 4, 2), Date.new(2020, 4, 1)) 67 assert_equal 19, Sample.schoolYear(Time.mktime(2000, 4, 2), Date.new(2020, 4, 2)) 68 assert_equal 19, Sample.schoolYear(Time.mktime(2000, 4, 2), Date.new(2020, 12, 31)) 69 end 70end

投稿2020/04/04 05:16

編集2020/04/04 05:31
hoshi-takanori

総合スコア7895

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

学年が決定されるのは「4/1時点での年齢」です。
ですから、誕生日と基準となる年の4/1から、その人の年齢を計算するべきですね。

Ruby

1age = (Date.today.strftime('%Y%m%d').to_i - birthday.strftime('%Y%m%d').to_i) / 10000

ここで年齢を「今日の時点で何歳か」で計算してしまっているから学年ではなくて満年齢の計算になってしまっています。
基準は

  • 今日が 4/1 以前なら、前年の4/1
  • 今日が 4/2 以後なら、今年の4/1

とすればよいのでは?

投稿2020/04/06 02:31

tacsheaven

総合スコア13703

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tatsu99

2020/04/06 04:15

小学1年=6歳で、この方法で計算すると(年齢は実年齢ではなく学年を決めるための年齢) 2013/3/31 生まれ 2020年4月1日:6歳(小学1年) 2020年4月2日:7歳(小学2年) 2013/4/1 生まれ 2020年4月1日:6歳(小学1年) 2020年4月2日:7歳(小学2年) 2013/4/2 生まれ 2020年4月1日:5歳(幼稚園 ) 2020年4月2日:6歳(小学1年) となってしまいます。 正しくは 2013/3/31 生まれ 2020年4月1日:7歳(小学2年) 2020年4月2日:7歳(小学2年) 2013/4/1 生まれ 2020年4月1日:7歳(小学3年) 2020年4月2日:7歳(小学2年) 2013/4/2 生まれ 2020年4月1日:6歳(小学1年) 2020年4月2日:6歳(小学1年) ではないでしょうか。
tacsheaven

2020/04/06 05:00

ん? today の代わりが 今年の4/1になるので、 20200401 - 20130331 = 70069 で 7才、 20200401 - 20130401 = 70000 で 7才、 20200401 - 20130402 = 69999 で 6才、 になるはずですが…today が 4/1 を境に見るべき基準年がずれます。
tatsu99

2020/04/06 05:10

「今日が 4/1 以前なら、前年の4/1」ということなので 今日が2020年4月1日なら、前年の4/1を採用するので、 20190401 - 20130331= 6歳 20190401 - 20130401= 6歳 20190401 - 20130402= 5歳 になりませんか?
guest

0

age = (Date.today.strftime('%Y%m%d').to_i - birthday.strftime('%Y%m%d').to_i) / 10000
の直後に以下の文を挿入してください。

Ruby

1 if birthday.strftime('%m%d').to_i >= "0402".to_i 2 oso_umare = true 3 else 4 oso_umare = false 5 end 6 if today.strftime('%m%d').to_i >= birthday.strftime('%m%d').to_i 7 have_birthday = true 8 else 9 have_birthday = false 10 end 11 if today.strftime('%m').to_i >= 4 12 if oso_umare == true && have_birthday == true 13 age = age - 1 14 end 15 else 16 if oso_umare == true || have_birthday == true 17 age = age - 1 18 end 19 end

hoshi-takanoriさんが指摘した通り、1学年は4月2日生まれから翌年の4月1日生まれの児童生徒で構成される前提です。
遅生まれは4月2日以降に生まれた生徒です。(oro_umare=true)
その年の誕生日を迎えた場合、have_birthday = trueとなります。
年齢算出時、
現在日が4月以降(4月含む)なら、遅生まれで、誕生日を迎えた場合、年齢から1を引きます。
現在日が3月以前(3月含む)なら、遅生まれ、又は誕生日を迎えた場合、年齢から1を引きます。

もし、1学年は4月1日生まれから翌年の3月31日生まれの児童生徒で構成される前提にしたいなら、
if birthday.strftime('%m%d').to_i >= "0402".to_i

if birthday.strftime('%m%d').to_i >= "0401".to_i
に変えてください。

実年齢と補正後の年齢

投稿2020/04/04 00:54

編集2020/04/06 02:31
tatsu99

総合スコア5438

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Nish

2020/04/04 01:37 編集

すいません。上記の追加コードを記入して実行してみたのですが、まだ誕生日で学年が変更さます。
tatsu99

2020/04/06 02:21

hoshi-takanoriさんの指摘をもとに書き換えました。
guest

0

年齢を出したうえで、誕生日が4/1以降かどうかで処理すればいいんじゃないでしょうか

投稿2020/04/04 00:31

y_waiwai

総合スコア87747

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問