13

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

5 に答える 5

16

これを行う1つの方法は次のとおりです。

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 
于 2012-12-16T05:41:33.833 に答える
15

まず、2 つの日付の間の月数を数えます ( 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 でテストされ、動作しています。

于 2012-12-16T07:03:05.457 に答える
7
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
于 2012-12-16T11:30:38.030 に答える