1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Last updated at Posted at 2019-11-05

改修してみました。

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

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

##実際に書いてみた

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桁ごとにカンマ表記にする →メソッド化
複数回同じ処理があるのでメソッド化しました。

ソースコード
###未入力の分岐を削除
以前は未入力も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の範囲で入力してもらう必要がある。

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

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

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

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

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

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

ソースコード
puts "本日は、#{today.strftime("%Y/%-m/%-d")}(#{weekend[today.wday]})です"
出力結果
本日は、2019/11/5() です

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

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?