Rai*_*ner 15 ruby ruby-on-rails ruby-on-rails-3 ruby-on-rails-3.2
示例我有:
range = start.to_date..(end.to_date + 1.day)
Run Code Online (Sandbox Code Playgroud)
结束和开始是日期.
如何基于此范围创建月份数组?
例:
我的日期是2012年1月23日和2012年3月15日
这几个月是Januar,Februar和Marts.
我想得到一个类似的数组 ["1/1/2012", "1/2/2012", "1/3/2012"]
如果范围在2012年6月25日至10月10日之间
数组将是: ["1/6/2012", "1/7/2012", "1/8/2012", "1/9/2012", "1/10/2012"]
Lar*_*eth 32
require 'date'
date_from = Date.parse('2011-10-14')
date_to = Date.parse('2012-04-30')
date_range = date_from..date_to
date_months = date_range.map {|d| Date.new(d.year, d.month, 1) }.uniq
date_months.map {|d| d.strftime "%d/%m/%Y" }
# => ["01/10/2011", "01/11/2011", "01/12/2011", "01/01/2012",
# "01/02/2012", "01/03/2012", "01/04/2012"]
Run Code Online (Sandbox Code Playgroud)
Rails ActiveSupport核心扩展包括Date:beginning_of_month的方法.您的功能可以写成如下:
def beginning_of_month_date_list(start, finish)
(start.to_date..finish.to_date).map(&:beginning_of_month).uniq.map(&:to_s)
end
Run Code Online (Sandbox Code Playgroud)
注意事项:这可以更有效地编写,假设开始和结束是按预期的顺序,但否则应该给你你正在寻找的月份.您还可以重写以将格式符号传递给#to_s方法以获取预期的月份格式.
我对这里的性能很好奇,所以我测试了一些变化。这是一个针对性能进行了更好优化的解决方案(在我的基准测试中,比公认的解决方案快大约 8 倍)。通过一次增加一个月,我们可以删除调用,uniq
这会节省相当多的时间。
start_date = 1.year.ago.to_date
end_date = Date.today
dates = []
date = start_date.beginning_of_month
while date <= end_date.beginning_of_month
dates << date.to_date.to_s
date += 1.month
end
dates
#=> ["2019-02-01", "2019-03-01", "2019-04-01", "2019-05-01", "2019-06-01", "2019-07-01", "2019-08-01", "2019-09-01", "2019-10-01", "2019-11-01", "2019-12-01", "2020-01-01", "2020-02-01"]
Run Code Online (Sandbox Code Playgroud)
基准测试结果:
Comparison:
month increment loop: 17788.3 i/s
accepted solution: 2140.1 i/s - 8.31x slower
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
12414 次 |
最近记录: |