我正在寻找一个简洁的方法来获得一系列日期,并考虑一年内的整个范围。
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 ...]
答案 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_date
和end_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_date
和end_date
可能会在不同年份出现。