如果您需要扩展到更有趣的逻辑,我认为您可能应该使用库,但是如果您所描述的就是您所需要的,那么下面的代码应该会有所帮助
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
我相信它可以被简化,我很想听听一些建议:)(太晚了,甚至懒得弄清楚有效日期的实际范围应该是多少,即小于-31..62)