如何从ruby中的日期列表中获取最新的一天

时间:2016-11-25 03:54:21

标签: arrays ruby date datetime

我正在寻找一个简洁的方法来获得一系列日期,并考虑一年内的整个范围。

days  = [1, 31]
dates = []
(start_date..end_date).each do |date|
  dates << if days.include? date.day
end

我所看到的是一个包含days所有日期的数组,如果该月份不存在,请使用最新的日期。

[nov 1, nov 30, dec 1, dec 31 ...]

1 个答案:

答案 0 :(得分:1)

require 'date'

days       = [1, 15, 31]
  #=> [1, 15, 31]
last_day   = days.max
  #=> 31
start_date = Date.parse 'Jan 4, 2016'
  #=> #<Date: 2016-01-04 ((2457392j,0s,0n),+0s,2299161j)>
end_date   = Date.parse 'Nov 16, 2016'
  #=> #<Date: 2016-11-16 ((2457709j,0s,0n),+0s,2299161j)> 

(start_date..end_date).select do |d|
  days.include?(d.day) || (((d+1).month != d.month) && (d.day < last_day))
end.map {|d| d.strftime("%b %-d")}
  #=> ["Jan 15", "Jan 31", "Feb 1",  "Feb 15", "Feb 29", "Mar 1",  "Mar 15",
  #    "Mar 31", "Apr 1",  "Apr 15", "Apr 30", "May 1",  "May 15", "May 31",
  #    "Jun 1",  "Jun 15", "Jun 30", "Jul 1",  "Jul 15", "Jul 31", "Aug 1",
  #    "Aug 15", "Aug 31", "Sep 1",  "Sep 15", "Sep 30", "Oct 1",  "Oct 15",
  #    "Oct 31", "Nov 1",  "Nov 15"] 

如果逻辑表达式返回d,则会选择start_dateend_date之间的每个日期对象true。逻辑表达式读取:“a)给定数组days包括d.day b)d.day是该月的最后一天那天小于last_day“。如果d.day下降的月份与第二天(d)下降的月份不同,则d+1是该月的最后一天。 (如果d属于12月31日(月12),则第二天属于1个月,因此我们必须测试12 != 1而不是12 < 1。)

有关格式代码的说明,请参阅Date#strftime

start_dateend_date可能会在不同年份出现。