在Rails中获取最后X个月的名称

时间:2016-07-21 17:28:28

标签: ruby-on-rails ruby

我正试图从过去的6个月中获得一系列月份名称。我已经看到其他帖子解决了迭代和打印实际日期7/1 / 16,7 / 2/16等问题,但没有任何关于月份名称的内容:

[“二月”,“三月”,“四月”,“五月”,“六月”,“七月”]

我正在尝试以下代码,但我收到此错误:

@array = []
(6.months.ago..Time.now).each do |m|
  @array.push(Date::MONTHNAMES[m])  
end 

TypeError: can't iterate from ActiveSupport::TimeWithZone

3 个答案:

答案 0 :(得分:3)

一个简单的,虽然有点天真的方式,将迭代整数并计算它落入哪个月,然后最终在数组中查找它。

5.downto(0).collect do |n| 
  Date::MONTHNAMES[n.months.ago.month]
end

这将返回 ["February", "March", "April", "May", "June", "July"](这是在7月份执行)

答案 1 :(得分:3)

基于Olives' answer构建的稍微丑陋的版本,但不需要在每个月查找日期,速度提高约31倍:

current_month = Date.today.month

month_names = 6.downto(1).map { |n| DateTime::MONTHNAMES.drop(1)[(current_month - n) % 12] }

current_month为4时的输出(测试Dec-Jan翻转):

["November", "December", "January", "February", "March", "April"] 

基准:

Benchmark.measure do
  10000.times do
    current_month = Date.today.month
    month_names = 6.downto(1).map { |n| DateTime::MONTHNAMES.drop(1)[(current_month - n) % 12] }
  end
end
=> #<Benchmark::Tms:0x007fcfda4830d0 @label="", @real=0.12975036300485954, @cstime=0.0, @cutime=0.0, @stime=0.07000000000000006, @utime=0.06999999999999984, @total=0.1399999999999999> 

与清洁版相比:

Benchmark.measure do
  10000.times do
    5.downto(0).collect do |n| 
        Date::MONTHNAMES[n.months.ago.month]
    end
  end
end
=> #<Benchmark::Tms:0x007fcfdcbde9b8 @label="", @real=3.7730263769917656, @cstime=0.0, @cutime=0.0, @stime=0.04999999999999993, @utime=3.69, @total=3.7399999999999998> 

答案 2 :(得分:0)

以下版本将以3个字符的月份格式显示:

5.downto(0).collect do |n| 
  Date.parse(Date::MONTHNAMES[n.months.ago.month]).strftime('%b')
end

输出 :(将当前月份视为1月)

  

[“ Aug”,“ Sep”,“ Oct”,“ Nov”,“ Dec”,“ Jan”]