2017-01-31 3 views
-1

2つの日付(Dateオブジェクト)があります。私は、その差が正確にXヶ月の倍数であるかどうかをチェックする必要があります(月と日の最後を考慮)。2つの日付の違いがXの月数の倍数であることを確認する方法

簡潔にするため、この質問ではXが4になるとします。

私が達成したい最も単純なロジックは、次の点です(モジュロは整数でしか動作しないように見えるため、FOUR_MONTHSは機能しません)。だから、私は次のことを模倣する任意の方法(私は単に見逃しているかもしれないこと)がありますかどうかを知りたいのです:

(Date.parse('2017-01-15') - Date.parse('2016-09-15')) % (FOUR_MONTHS) == 0 
(Date.parse('2017-01-15') - Date.parse('2016-09-14')) % (FOUR_MONTHS) != 0 
(Date.parse('2017-01-15') - Date.parse('2016-05-15')) % (FOUR_MONTHS) == 0 
(Date.parse('2017-01-31') - Date.parse('2016-09-30')) % (FOUR_MONTHS) == 0 
(Date.parse('2016-11-30') - Date.parse('2016-07-31')) % (FOUR_MONTHS) == 0 
(Date.parse('2016-11-30') - Date.parse('2016-07-30')) % (FOUR_MONTHS) == 0 

は、現時点では、私は各FOUR_MONTHSをループと考えることができますが、私はそれを考えています効率的ではなく、より単純な方法があるかもしれないし、まったく単純なRubyメソッドを見逃してしまったかもしれません。

P.S. ActiveSupport::TimeZoneは実装上の違いがある可能性があるので、私はこの質問にルビー・オン・レールを付けてタグ付けしています。

+1

この質問は、注意が必要ですあなたはactivesupportののmonths_agoまたはmonths_sinceメソッドを使用することができます。回答者が何かをコーディングすることを期待する前に、試したことを示す必要があります。 –

+1

@EricDuminil、あなたは正しいです。私は数分で私の答えを更新して、ループしているので非効率的だと思う。 –

+0

合法であっても、downvotesのために今stackoverflowを嫌いにし始めている理由の1つ。私は意図的にサンプル回答を書いていませんでした。効率の悪い方が良い方法があると確信しています。みんなもっと気にしてください。 –

答えて

1

これはRailsの(end_of_monthが必要とされている)で正常に動作する必要があります:

def month_id(date) 
    date.month + date.year * 12 
end 

def same_day?(date1, date2) 
    (last_day_of_month?(date1) && date2.day >= date1.day) || 
    (last_day_of_month?(date2) && date1.day >= date2.day) || 
    date1.day == date2.day 
end 

def last_day_of_month?(date) 
    date == date.end_of_month 
end 

def separated_by_multiple_of_x_months?(date1, date2, x = 4) 
    same_day?(date1, date2) && (month_id(date1) - month_id(date2)) % x == 0 
end 

separated_by_multiple_of_x_months?(Date.parse('2017-01-15'), Date.parse('2016-09-15')) 
#=> true 
separated_by_multiple_of_x_months?(Date.parse('2017-01-15'), Date.parse('2016-09-14')) 
#=> false 
separated_by_multiple_of_x_months?(Date.parse('2017-01-15'), Date.parse('2016-05-15')) 
#=> true 
separated_by_multiple_of_x_months?(Date.parse('2017-01-31'), Date.parse('2016-09-30')) 
#=> true 
separated_by_multiple_of_x_months?(Date.parse('2016-11-30'), Date.parse('2016-07-31')) 
#=> true 
separated_by_multiple_of_x_months?(Date.parse('2016-11-30'), Date.parse('2016-07-30')) 
#=> true 
+0

私のポイントはすでに十分に明確だと思った。しかし正確に言えば、私はRubyがどのように月を追加/減算するか、すなわち最初の日付の日が31で、1monthで追加された場合、結果の日付/合計はその月の可能な最高値です31,30または28または29) –

+0

回答が更新されました。 –

+0

これは素晴らしいです!ありがとう –

0

あなたはto_iを行う場合は、日中の違いを取得します(end_date - start_date % x * (30.days/1.day)).to_i.zero?

+0

これは上記のすべての点を満たしていません。月間は常に30日ではない、または月末の日数が考慮される場合 –

+0

質問はここでは具体的ではありません。 xヶ月は何ですか?最後のx月ですか?今年の最初の数ヶ月?開始日より前の最後のx月、または終了日より前のx月、またはその間の何日ですか? – michaeldever

+0

私のポイントを読んでください。私は6つのシナリオを立てました。私は、無礼ではないはずですが、私の質問はそれが年の最後のxか最初のxヶ月かどうかは気にしません。あなたが正しいので、私は "to_i"を使用することができますが、私はまだ月の最後の日をチェックする必要があるので、私はその方法を使用する場合はまだもう一つのステップが必要です –

0

ような何かを試みることができる:

(Date.parse('2017-01-15') - Date.parse('2016-09-15')).to_i 
+0

はい。しかし間にある日数は間違っていますが、その間の月数は私が望むものです –

+0

月が30日あると仮定すると、days%30 == 0 && days/30 – leifg

+0

yesです。私はそれを行うことができます。それはまだ "月末の最後の日"を考慮していません –

0

OK 2回目です。

と仮定すると、日付1が日付2よりも小さい:日付がトリッキーなので、

def months_apart?(date1, date2, num_of_months) 
    date2.months_ago(num_of_months) == date1 
end 
+0

私はそれについても考えました。しかし、OPは「数ヶ月の数ヶ月」を探している。それは4であり、8であり、-4であり得る。 –

+0

@leifg助けてくれてありがとう、しかしエリックはそれに答えました:) –

関連する問題