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

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

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

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

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Q&A

解決済

2回答

1069閲覧

○ヶ月○日と表示させたい

makox0105

総合スコア65

Ruby

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

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

0グッド

0クリップ

投稿2020/08/12 09:07

編集2020/08/13 04:55

日付の差分を出して○ヶ月○日というように表示させたいです。
月に応じて31日だったり30日だったりを考慮した日付を出したいです。
ExcelでいうDAYTDIF関数のような表示のさせ方です。

a = 2020/7/3
b = 2020/8/11

b - a = 1ヶ月9日(40日)

日数はこれで得られますが、
(b - a + 1).to_i

これを1ヶ月9日と表示させたいです。

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

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

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

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

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

winterboum

2020/08/12 09:43

39日になるとおもうのですが、両端を入れる? 8/2までを一ヶ月として、8/3は1ヶ月1日ですか? それとも8/3は1ヶ月0日?
makox0105

2020/08/12 09:46

コメントありがとうございます。 1ヶ月1日です。
gouf

2020/08/12 10:09

表示させたいのは「経過した月日」のみですか? 起点とする日付以前を表示させることはありますか?
makox0105

2020/08/12 11:48

コメントありがとうございます。期間なので、経過した月日のみということになります。
guest

回答2

0

「開始日から終了日までの間隔を変えずに、開始日をその月の初日に平行移動させる」というイメージで書くと以下になるでしょうか。ただ、両端の処理については、質問文からすると意図通りではないかもしれません……。

ruby

1# frozen_string_literal: true 2 3def date_diff(former, latter) 4 require 'date' 5 6 a = Date.parse(former) 7 b = Date.parse(latter) 8 9 a_new = Date.new(a.year, a.month, 1) 10 b_new = a_new + (b - a).to_i 11 12 month = b_new.month - a_new.month 13 day = b_new.day - 1 14 15 %(#{month}ヶ月#{day}日) 16end 17 18a = '2020/7/3' 19b = '2020/8/11' 20puts date_diff(a, b) #=> 1ヶ月8日 21 22c = '2020/07/01' 23d = '2020/07/02' 24puts date_diff(c, d) #=> 0ヶ月1日 25 26e = '2020/07/31' 27f = '2020/08/01' 28puts date_diff(e, f) #=> 0ヶ月1日

投稿2020/08/12 10:14

gemmaro

総合スコア358

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

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

makox0105

2020/08/12 12:08

すみません、VIEWで表示させるには、これをHelperに書けば良いですか?初歩的な質問で申し訳ありません。
gemmaro

2020/08/12 12:29

私はこれまで Ruby on Rails に触れたことがなく、お答えできません。ごめんなさい。
makox0105

2020/08/12 12:39

いえいえ、ありがとうございました。
guest

0

ベストアンサー

それっぽく動くコードを書いてみました

ruby

1require 'active_support' 2require 'active_support/core_ext' 3 4def date_duration(base_date, after_date) 5 duration_parts = 6 ActiveSupport::Duration.build(after_date.to_i - base_date.to_i).parts 7 # 起点日も 1日としてカウントする (+1) 8 duration_in_days = (after_date - base_date).to_i + 1 9 10 years, months, days, weeks = 11 duration_parts[:years], duration_parts[:months], duration_parts[:days], duration_parts[:weeks] 12 13 # * n週 に吸収された値を還元 (n weeks * 7 days) 14 # * 起点日も 1日としてカウントする (+1) 15 days += weeks * 7 + 1 16 17 case [years, months, days] 18 in [0, 0, 0] then "今日" 19 in [0, 0, _] then "#{days}日後" 20 in [0, _, 0] then "#{months}ヶ月後" + "(#{duration_in_days}日)" 21 in [0, _, _] then "#{months}ヶ月#{days}日後(#{duration_in_days}日)" 22 in [_, 0, 0] then "#{years}年後" + "(#{duration_in_days}日)" 23 in [_, _, 0] then "#{years}#{months}ヶ月後" + "(#{duration_in_days}日)" 24 in [_, 0, _] then "#{years}年" + "#{days}日後(#{duration_in_days}日)" 25 else "#{years}#{months}ヶ月#{days}日後(#{duration_in_days}日)" 26 end 27end 28 29date_time_args = [ 30 2020, # year 31 7, # month 32 3, # day 33 0, # hour 34 0, # min 35 0, # sec 36 '+09:00' # time zone 37] 38 39base_date = DateTime.new(*date_time_args) 40after_date = base_date.advance(years: 0, months: 1, days: 8) 41 42# For debug 43format = '%Y/%m/%d' 44pp [base_date, after_date].map { |x| x.strftime(format) } 45# => ["2020/07/03", "2020/08/11"] 46 47pp date_duration(base_date, after_date) 48# => "1ヶ月9日後(40日)" 49

地獄のようなコードを書いた気がしますが、なにか参考になれば幸いです

(※ Ruby 2.7 系のパターンマッチングは実験的な機能なので、今後うごかなくなるかもしれません)

Link

投稿2020/08/12 12:20

編集2020/08/12 12:30
gouf

総合スコア2321

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

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

makox0105

2020/08/12 12:29

うわっ、ありがとうございます。でも使い方がわからない…。
gouf

2020/08/12 19:00

base_date に起点とする日付を, after_date に起点より後の日付を、date_duration 関数に入力してあげるだけです その際、引数それぞれを DateTime 型で渡すことに注意してください (ActiveSupport::Duration.build が DateTime#to_i の形式を必要としているみたいなので 少しサボって DateTime のみを受け付けるように書きました。少し書き換えれば Date 型も受けられるようになるかもしれません)
makox0105

2020/08/13 00:59

わかりました。色々やってみます。
makox0105

2020/08/13 01:32

これってHelperに書けば良いのですか?
winterboum

2020/08/13 06:05

「日付」を持っているmodelのmethodにするのがお薦めです。 「必要な情報を持っている class に仕事させる」 それですとmodelからそれらも手に入るので、引数なしで実装できます。
makox0105

2020/08/13 06:13

We're sorry, but something went wrong.と出でしまいます。私が何か操作を間違っているのでしょうか…?
winterboum

2020/08/13 06:14

logみるとなにが悪いか出ています
makox0105

2020/08/13 06:23

warning: else without rescue is useless Completed 500 Internal Server Error in 16ms (ActiveRecord: 1.0ms) と出てます。
makox0105

2020/08/13 06:25

ArgumentError: invalid byte sequence in UTF-8 とも出てます。
winterboum

2020/08/13 06:29

proguram全体を見る必要がありそうですね。 logのその辺りにどのふぃぇのどの行か出ているはずですから、 そのfileとlogの該当部分を載せて質問しましょう・ ただ、「この質問」とは別の質問になりますから、goufさんの回答で納得でしたら、ここは閉めたほうがよいでしょう。
makox0105

2020/08/13 07:01

わかりました。ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問