より興味深いロジックに分岐する必要がある場合は、おそらくライブラリを使用する必要があると思いますが、説明したものが必要なだけの場合は、以下のコードが役立つはずです
SECONDS_PER_DAY = 60 * 60 * 24
def find_tuesday_datenight(now)
tuesdays = [*-31..62].map { |i| now + (SECONDS_PER_DAY * i) }
.select { |d| d.tuesday? }
.group_by { |d| d.month }
[tuesdays[now.month][1], tuesdays[now.month][-2], tuesdays[(now.month + 1) % 12][1]]
.find {|d| d.yday > now.yday }
end
先月と翌月をループし、火曜日を取得し、月ごとにグループ化し、現在の月の 2 番目と 2 番目の最後の火曜日 (実際に 4 番目の火曜日が必要な場合は、-2 を 3 に変更します) と 2 番目の火曜日を取得します。翌月の日付を選択し、指定された日付の後の最初の日付を選択します。
ここにいくつかのテスト、月に4回の火曜日、月に5回の火曜日、ランダム、およびあなたの例があります:
[[2013, 5, 1], [2013, 12, 1], [2012, 10, 1], [2012, 10, 19], [2012, 10, 31]].each do |t|
puts "#{t} => #{find_tuesday_datenight(Time.new *t)}"
end
生産する
[2013, 5, 1] => 2013-05-14 00:00:00 +0800
[2013, 12, 1] => 2013-12-10 00:00:00 +0800
[2012, 10, 1] => 2012-10-09 00:00:00 +0800
[2012, 10, 19] => 2012-10-23 00:00:00 +0800
[2012, 10, 31] => 2012-11-13 00:00:00 +0800
私はそれが単純化される可能性があると確信しており、いくつかの提案を聞きたいです:)