获得两个日期之间的月份和年份的独特数组

时间:2017-07-12 17:45:01

标签: ruby-on-rails ruby

我有两个Date个对象,例如:

first = Fri, 02 Dec 2016 
last = Wed, 01 Mar 2017

在它们之间获得独特数月和数年的最有效方法是什么?在这种情况下,我在追求:

Dec 2016
Jan 2017
Feb 2017
Mar 2017

6 个答案:

答案 0 :(得分:4)

require 'date'

def doit(first, last)
  (12*last.year + last.month - 12*first.year - first.month).times.map do
    first.strftime("%b %Y")
    first = first >> 1
  end
end

first = Date.parse('Fri, 02 Dec 2016')
last  = Date.parse('Wed, 01 Mar 2017')
doit(first, last)
  #=> ["Dec 2016", "Jan 2017", "Feb 2017", "Mar 2017"]

答案 1 :(得分:3)

您可以创建一个日期数组,然后使用strftime设置正确的格式,并uniq以避免重复的值,如下所示:

(first..last).map{ |date| date.strftime("%b %Y") }.uniq
#=> ["Dec 2016", "Jan 2017", "Feb 2017", "Mar 2017"]

答案 2 :(得分:3)

由于用户要求 最有效的方式 (并且只是为了好玩),这里是建议解决方案的简单基准:

require 'benchmark'

Benchmark.bmbm(10) do |bm|
  bm.report('Cary') do
    first = Date.new(1000, 1, 1)
    last  = Date.new(2100, 1, 1)

    def doit(first, last)
      (12*last.year + last.month - 12*first.year - first.month).times.map do
        first.strftime("%b %Y")
        first = first >> 1
      end
    end

    doit(first, last)
  end

  bm.report('Simple Lime') do
    first = Date.new(1000, 1, 1)
    last  = Date.new(2100, 1, 1)

    dates = []

    while first.beginning_of_month < last.end_of_month
      dates << first.strftime("%b %Y")

      first = first.next_month
    end
  end

  bm.report('Máté') do
    first = Date.new(1000, 1, 1)
    last  = Date.new(2100, 1, 1)

    (first.beginning_of_month..last).map { |d| d.strftime("%b %Y") if d.day == 1 }.compact
  end

  bm.report('Gerry/Dan') do
    first = Date.new(1000, 1, 1)
    last  = Date.new(2100, 1, 1)

    (first..last).map{ |date| date.strftime("%b %Y") }.uniq
  end
end

结果:

Rehearsal -----------------------------------------------
Cary          0.020000   0.000000   0.020000 (  0.025968)
Simple Lime   0.190000   0.000000   0.190000 (  0.192860)
Máté          0.460000   0.020000   0.480000 (  0.481839)
Gerry/Dan     0.810000   0.020000   0.830000 (  0.835931)
-------------------------------------- total: 1.520000sec

                  user     system      total        real
Cary          0.020000   0.000000   0.020000 (  0.024871)
Simple Lime   0.150000   0.000000   0.150000 (  0.150696)
Máté          0.390000   0.010000   0.400000 (  0.398637)
Gerry/Dan     0.710000   0.010000   0.720000 (  0.711155)

答案 3 :(得分:2)

不是一个漂亮的单行,但也没有单独走过每一天,所以对于大范围应该更快一点。

first = Date.new(2016, 12, 2)
last = Date.new(2017, 3, 1)

dates = []
while first.beginning_of_month < last.end_of_month
  dates << first.strftime("%b %Y")

  first = first.next_month
end

puts dates.inspect
# => ["Dec 2016", "Jan 2017", "Feb 2017", "Mar 2017"]

答案 4 :(得分:1)

假设这些变量:

>>> type(int)
<type 'type'>
>>> type.__dict__['__name__']
<attribute '__name__' of 'type' objects>
>>> type.__dict__['__name__'].__get__(int)
'int'

单线解决方案:

first = Date.new(2016, 12, 2)
last = Date.new(2017, 3, 1)

答案 5 :(得分:1)

start_date=Date.new(2016,12,2)
end_date=Date.new(2017,3,1)

(start_date..end_date).map{ |d| d.strftime("%b %Y") }.uniq
 => ["Dec 2016", "Jan 2017", "Feb 2017", "Mar 2017"]