Rubyで日付判定して過去日なら経過日数、未来なら何日後が表示されるアプリを作ってみた(2)

改修してみました。

##仕様要件
・入力した日付の正当性をチェックをする
・過去日なら経過日数を表示する
・未来日なら何日後なのか表示させる

・未入力はNG、必ず入力させる


##実際に書いてみた
```ruby:day_count.rb
require "date"

# 整数を3桁ごとにカンマ表記にする
def int_comma(i)
  i.to_s.gsub(/(?<=\d)(?=\d{3}+$)/, ',')
end

# 今日の日付取得、表示
today = Date.today
weekend = %w(日 月 火 水 木 金 土)
puts "本日は、#{today.strftime("%Y/%-m/%-d")}(#{weekend[today.wday]})です"

input_year = nil
puts "\n指定日時を設定します"

# 指定年を入力
loop_flg = 0
while loop_flg == 0 do
  puts "\n指定年を4桁の整数で入れてください。小数を入力した場合は整数部分のみ認識されます"
  # 入力文字列を変数に代入
  input_year = gets.to_i

  if input_year.between?(1000, 9999)
    # 正しく入力されたのでループ解除
    loop_flg = 1
  else
    # 入力値が1000～9999以外の場合のルート
    puts "入力した値は1000から9999のいずれかではありません"
  end
end

# 指定月を入力
loop_flg = 0
while loop_flg == 0 do
  puts "\n指定月を1～12以下の整数で入れてください。小数を入力した場合は整数部分のみ認識されます"
  # 入力文字列を変数に代入
  input_month = gets.to_i

  if input_month.between?(1, 12)
    # 正しく入力されたのでループ解除
    loop_flg = 1
  else
    # 入力値が1〜12以外の場合のルート
    puts "入力した値は1から12のいずれかではありません"
  end
end

# 指定日を入力
loop_flg = 0
while loop_flg == 0 do
 puts "\n指定日を指定年月に合わせた整数で入れてください。小数を入力した場合は整数部分のみ認識されます"
 # 入力文字列を変数に代入
 input_day = gets.to_i

 # 実在する日付か判定する
 if Date.valid_date?(input_year, input_month, input_day)
  # 正しく入力されたのでループ解除
  loop_flg = 1
 else
  puts "入力した値は日付として正しくありません"
 end
end

# 入力値を日付フォーマットで代入
input_date = Date.new(input_year, input_month, input_day)
puts "\n入力した指定日時は、#{input_date.strftime("%Y/%-m/%-d")}(#{weekend[input_date.wday]})です"

# 時系列判定
if input_date == today
  puts "指定日は今日です"
elsif input_date < today
  # 指定した日付からの経過日数
  puts "過去日になるので経過日数を表示します"
  calc_date1 = today - input_date
  puts "指定日から今日まで、#{int_comma(calc_date1.to_i)}日経過しています"

  # 10,000日後の日付
  calc_day2 = 10000
  calc_date2 = input_date + calc_day2
  puts "\nまた指定日から#{int_comma(calc_day2.to_i)}日後は、#{calc_date2.strftime("%Y/%-m/%-d")}(#{weekend[calc_date2.wday]})になります"
else
  # 指定した日付までの残日数
  puts "未来日になるので何日後なのか表示します"
  calc_date3 = input_date - today
  puts "指定日は本日から#{int_comma(calc_date3.to_i)}日後です"
end

exit
```

##ソースコードで使ったもの

###整数を3桁ごとにカンマ表記にする →メソッド化
複数回同じ処理があるのでメソッド化しました。

```ruby:ソースコード
###未入力の分岐を削除
以前は未入力もOKとしていましたが、NGの仕様にしました。
これによって厳密な入力が必要になっていきます。

```ruby:ソースコード
# 指定年を入力
loop_flg = 0
while loop_flg == 0 do
  puts "\n指定年を4桁の整数で入れてください。小数を入力した場合は整数部分のみ認識されます"
  # 入力文字列を変数に代入
  input_year = gets.to_i

  if input_year.between?(1000, 9999)
    # 正しく入力されたのでループ解除
    loop_flg = 1
  else
    # 入力値が1000～9999以外の場合のルート
    puts "入力した値は1000から9999のいずれかではありません"
  end
end
```

ループフラグをONにしつつ、入力処理を行い、4桁の整数(=1000〜9999)に該当した場合のみループフラグをOFFにし、そうでない場合はもう一度入力させるようにする。

入力文字の型はint型を指定しているので、小数点以下は無視する仕様になっており、1000未満の数値も10000以上ももう一度ループさせるようにしました。

「年」だけでなく「月」も同様です。

###範囲指定を条件にする
年だと1000〜9999、月だと1〜12の範囲で入力してもらう必要がある。

```ruby:ソースコード
if input_year.between?(1000, 9999)
```

上記は、1000〜9999の範囲だとtrueを返すようになっている

###日付の正当性チェック →メソッド化をやめた
1回しか処理がなく、冗長性ないのでメソッド化をやめました。
（年、月は正当性チェック入れず、範囲内の数字なら通るようにしているので）

```ruby:ソースコード
#Date.valid_date?(年, 月, 日)で指定する
if Date.valid_date?(input_year, input_month, input_day)
#=>正しい日付ならtrueを返し、そうでない場合はfalseを返す
```

valid_date関数で引数の年月日の正当性を確認します。

###日付フォーマットを指定して表示させる
Dateクラスで指定した要素からstrftimeメソッドを使って日時データを文字列に変換する

```ruby:ソースコード
puts "本日は、#{today.strftime("%Y/%-m/%-d")}(#{weekend[today.wday]})です"
```

```ruby:出力結果
本日は、2019/11/5(火) です
```

##次は何しようか
ブラッシュアップするか、新しいのを作るか