首页 文章

如何在Ruby on Rails中循环几个月

提问于
浏览
9

我需要在Ruby on Rails应用程序中循环几个月 . 对于每个月,我需要找到该月的第一天和最后一天 . 然后在单独的查询中使用这些日期来查找在这些日期期间发生的事件并对它们运行计算 .

最初,我尝试过类似的东西:

(11.months.ago.to_date.month..Date.today.month).each do |m|
  start_date = '01-#{m}-#{Date.today.year}'.to_date.beginning_of_month
  end_date = '01-#{m}-#{Date.today.year}'.to_date.end_of_month
end

当然,如果11个月前涉及回到上一年,那么这一年的情况不会更新 . 并且,我不认为这种类型的for / each循环有效 . 我也尝试将数字映射到数组并使用相同的方法,但收到错误 .

完成这样的事情的最佳方法是什么?

4 回答

  • 12

    首先,计算两个日期之间的月数(由Massimiliano Peluso提供):

    start_date = 13.months.ago.to_date
    # => Wed, 16 Nov 2011
    
    end_date = Date.today
    # => Sun, 16 Dec 2012
    
    number_of_months = (end_date.year*12+end_date.month)-(start_date.year*12+start_date.month)
    # => 13
    

    然后从开始月份开始计算每个月后,找到第一个/最后一个日期并附加到累加器数组 .

    dates = number_of_months.times.each_with_object([]) do |count, array|
      array << [start_date.beginning_of_month + count.months,
                start_date.end_of_month + count.months]
    end
    # => ...
    

    现在 dates 将包含一个数组,其中包含与每个月的第一个和最后一个日期对应的嵌套 Date 对 . 这个 dates 数组很容易迭代进行处理 .

    dates
    # => [[Tue, 01 Nov 2011, Wed, 30 Nov 2011], [Thu, 01 Dec 2011, Fri, 30 Dec 2011], ...
    
    dates[0].first
    # => Tue, 01 Nov 2011
    
    dates[0].last
    # => Wed, 30 Nov 2011
    
    dates[0].last.class
    # => Date
    

    这是在Rails 3.2.5 / Ruby 1.9.3p194中测试和使用的

  • 7
    (start_date..end_date).select{|date| date.day == 1}.map{|date| [date.beginning_of_month, date.end_of_month]}
    
  • 13

    这是一种方法:

    number_of_months = 0..11
    number_of_months.to_a.reverse.each do |month_offset|
      start_date = month_offset.months.ago.beginning_of_month
      end_date = month_offset.months.ago.end_of_month
      puts "Start date : #{start_date} End date : #{end_date}"
    end
    

    =>

    Start date : 2012-01-01 00:00:00 -0700 End date : 2012-01-31 23:59:59 -0700
    Start date : 2012-02-01 00:00:00 -0700 End date : 2012-02-29 23:59:59 -0700
    Start date : 2012-03-01 00:00:00 -0700 End date : 2012-03-31 23:59:59 -0600
    Start date : 2012-04-01 00:00:00 -0600 End date : 2012-04-30 23:59:59 -0600
    Start date : 2012-05-01 00:00:00 -0600 End date : 2012-05-31 23:59:59 -0600
    Start date : 2012-06-01 00:00:00 -0600 End date : 2012-06-30 23:59:59 -0600
    Start date : 2012-07-01 00:00:00 -0600 End date : 2012-07-31 23:59:59 -0600
    Start date : 2012-08-01 00:00:00 -0600 End date : 2012-08-31 23:59:59 -0600
    Start date : 2012-09-01 00:00:00 -0600 End date : 2012-09-30 23:59:59 -0600
    Start date : 2012-10-01 00:00:00 -0600 End date : 2012-10-31 23:59:59 -0600
    Start date : 2012-11-01 00:00:00 -0600 End date : 2012-11-30 23:59:59 -0700
    Start date : 2012-12-01 00:00:00 -0700 End date : 2012-12-31 23:59:59 -0700
    
  • 6
    time_start = 13.months.ago
    time_end = 0.seconds.ago
    time = time_start
    while time < time_end
      puts("m:#{time.month} y:#{time.year}")
      time = time.advance(months: 1)
    end
    

相关问题