我似乎无法找到一种优雅的方式来做到这一点……
在给定日期的情况下,如何找到下一个星期二,即该日历月的第二个或第四个星期二?
例如:
鉴于2012-10-19然后返回2012-10-23
要么
鉴于2012-10-31然后返回2012-11-13
October November Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa 1 2 3 4 5 6 1 2 3 7 8 9 10 11 12 13 4 5 6 7 8 9 10 14 15 16 17 18 19 20 11 12 13 14 15 16 17 21 22 23 24 25 26 27 18 19 20 21 22 23 24 28 29 30 31 25 26 27 28 29 30
解决方法
如果您只想查看最终结果的样子,请滚动到底部.
使用我最近在ruby 1.9.3中完成的一些日期处理工作的代码片段.
对DateTime的一些升级:
require 'date' class DateTime ALL_DAYS = [ 'sunday','monday','tuesday','wednesday','thursday','friday','saturday' ] def next_week self + (7 - self.wday) end def next_wday (n) n > self.wday ? self + (n - self.wday) : self.next_week.next_day(n) end def nth_wday (n,i) current = self.next_wday(n) while (i > 0) current = current.next_wday(n) i = i - 1 end current end def first_of_month self - self.mday + 1 end def last_of_month self.first_of_month.next_month - 1 end end
method_missing技巧:
我还补充了这个类,有一些方法缺少技巧来映射next_tuesday到next_wday(2)和first_tuesday(2)tonth_wday(2,2)`的调用,这使得下一个片段在眼睛上更容易.
class DateTime # ... def method_missing (sym,*args,&block) day = sym.to_s.gsub(/^(next|nth)_(?<day>[a-zA-Z]+)$/i,'\k<day>') dindex = ALL_DAYS.include?(day) ? ALL_DAYS.index(day.downcase) : nil if (sym =~ /^next_[a-zA-Z]+$/i) && dindex self.send(:next_wday,dindex) elsif (sym =~ /^nth_[a-zA-Z]+$/i) && dindex self.send(:nth_wday,dindex,args[0]) else super(sym,&block) end end def respond_to? (sym) day = sym.to_s.gsub(/^(next|nth)_(?<day>[a-zA-Z]+)$/i,'\k<day>') (((sym =~ /^next_[a-zA-Z]+$/i) || (sym =~ /^nth_[a-zA-Z]+$/i)) && ALL_DAYS.include?(day)) || super(sym) end end
例:
给定日期:
today = DateTime.Now second_tuesday = (today.first_of_month - 1).nth_tuesday(2) fourth_tuesday = (today.first_of_month - 1).nth_tuesday(4) if today == second_tuesday puts "Today is the second tuesday of this month!" elsif today == fourth_tuesday puts "Today is the fourth tuesday of this month!" else puts "Today is not interesting." end
您还可以编辑method_missing来处理调用,例如:second_tuesday_of_this_month,:fourth_tuesday_of_this_month等.如果我决定在以后编写代码,我会在此处发布代码.