如何根据日期范围创建月份数组

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何根据日期范围创建月份数组相关的知识,希望对你有一定的参考价值。

我有的例子:

  range = start.to_date..(end.to_date + 1.day)

结束和开始是日期。

如何根据此范围创建月份数组?

示例:

我有2012年1月23日和2012年3月15日的日期

月份是Januar,Februar和Marts。

我想要一个像["1/1/2012", "1/2/2012", "1/3/2012"]的数组

并且如果范围介于2012年6月25日至2012年10月10日之间

该数组为:["1/6/2012", "1/7/2012", "1/8/2012", "1/9/2012", "1/10/2012"]

答案
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"] 
另一答案

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

注意:这可以更有效地编写,假设开始和结束按预期的顺序进行,但是否则可以为您提供所需的时间。您也可以重写以将格式符号传递给#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"]

基准测试结果:

Comparison:
month increment loop:    17788.3 i/s
accepted solution:       2140.1 i/s - 8.31x  slower

gist of the benchmark code

以上是关于如何根据日期范围创建月份数组的主要内容,如果未能解决你的问题,请参考以下文章

如何使用函数匹配指定日期在另一个表日期范围内对应的数据?

Objective-C中的领域日期范围查询

日期选择器如何从下拉列表中选择月份

如何按日期合并 DF,仅使用日期和月份,使用指定的日期范围

如何根据一定的逻辑创建一个检索年份的函数

MySQL中根据日期进行范围查询