7

我正在使用 Chronic 来获取任何给定年份的月份的最后一个星期日。它会很乐意给我第n个星期日,但不是最后一个。

这有效,但不是我需要的:

Chronic.parse('4th sunday in march', :now => Time.local(2015,1,1))

这是我需要的,但不起作用:

Chronic.parse('last sunday in march', :now => Time.local(2015,1,1))

有什么办法可以绕过这个明显的限制吗?

更新:我赞成下面的两个答案,因为它们都很好,但我已经在“纯 Ruby”中实现了这个(在 2 行代码中,除了require 'date'一行),但我试图向管理层展示Ruby 是用来替换即将消失的 Java 代码库的正确语言(并且它有几十行代码来计算它),我告诉一位经理我可能可以用一行 Ruby 来完成它,它将是可读且易于维护的。

4

5 回答 5

10

我不确定Chronic(我以前没听说过),但我们可以用纯红宝石实现它:)

##
# returns a Date object being the last sunday of the given month/year
# month: integer between 1 and 12
def last_sunday(month,year)
  # get the last day of the month
  date = Date.new year, month, -1
  #subtract number of days we are ahead of sunday
  date -= date.wday
end

last_sunday方法可以这样使用:

last_sunday 07, 2013
#=> #<Date: 2013-07-28 ((2456502j,0s,0n),+0s,2299161j)>
于 2013-07-31T14:53:20.560 回答
4

阅读您问题中的更新后,我尝试仅使用一行 ruby​​ 代码(不使用 gems)提出另一个答案。这个怎么样?

##
# returns a Date object being the last sunday of the given month/year
# month: integer between 1 and 12
def last_sunday(month,year)
  # get the last day of the month, go back until we have a sunday
  Date.new(year, month, -1).downto(0).find(&:sunday?)
end

last_sunday 07, 2013
#=> #<Date: 2013-07-28 ((2456502j,0s,0n),+0s,2299161j)>
于 2013-07-31T19:17:06.257 回答
3

关于什么

Chronic.parse('last sunday', now: Chronic.parse('last day of march'))
于 2013-07-31T19:16:57.170 回答
3

这行得通,并且尽可能地可读:

Chronic.parse('last sunday', now: Date.new(year,3,31))

感谢 Ismael Abreu 提出的仅解析“上周日”并通过:now选项控制其余部分的想法。

更新:也请赞成伊斯梅尔的回答。

于 2013-07-31T20:37:36.243 回答
1

这有点难看,但你可以简单地按顺序尝试第 5 或第 4:

d = [5,4].each do |i| 
  try = Chronic.parse("#{i}th sunday in march", :now => Time.local(2015,1,1))
  break try unless try.nil?
end
 => Sun Mar 29 12:30:00 +0100 2015

d = [5,4].each do |i| 
  try = Chronic.parse("#{i}th sunday in april", :now => Time.local(2015,1,1))
  break try unless try.nil?
end
 => Sun Apr 26 12:00:00 +0100 2015
于 2013-07-31T14:58:02.763 回答