бесконечный цикл в задаче рейка, повторяющейся в диапазоне дат ActiveSupport


У меня проблема с моей задачей рейка, висящей в бесконечной петле. До сих пор мне удавалось изолировать проблему в виде фрагмента кода, преобразующего диапазон дат в массив. Даже если я прямо взываю к этому:

(1.month.ago.beginning_of_month..1.month.ago.end_of_month).to_a.each {|d| p d}

Задача нависает над одними и теми же элементами вечно:

"2012-06-01 00:40:41 UTC"
"2012-06-01 00:40:41 UTC"
"2012-06-01 00:40:41 UTC"
"2012-06-01 00:40:41 UTC"
"2012-05-31 20:40:41 UTC"
"2012-05-31 20:40:41 UTC"
"2012-06-01 00:40:42 UTC"
"2012-06-01 00:40:42 UTC"
"2012-06-01 00:40:42 UTC"
"2012-06-01 00:40:42 UTC"
"2012-05-31 20:40:42 UTC"
"2012-05-31 20:40:42 UTC"
...

Если вместо этого я использую это

(Date.new(2012,6,1)..Date.new(2012,6,30)).to_a.each {|d| p d}

Все работает, поэтому это должно быть что-то с использованием расширений ActiveSupport для даты/времени конкретно. Кто-нибудь еще видел это?

Это происходит в среде разработки на коробке Windows с Rails 3.1 и Ruby 1.9.3, если это имеет значение.

2 2

2 ответа:

Вы создаете диапазон Time в течение месяца с шагом в 1 секунду и ~2,5 миллиона записей:

(1.month.ago.beginning_of_month..1.month.ago.end_of_month)
# => Fri, 01 Jun 2012 00:00:00 CEST +02:00..Sat, 30 Jun 2012 23:59:59 CEST +02:00
1.month.ago.beginning_of_month.succ
# => Fri, 01 Jun 2012 00:00:01 CEST +02:00

Для создания диапазона Date Используйте:

(1.month.ago.beginning_of_month.to_date..1.month.ago.end_of_month.to_date)
# => Fri, 01 Jun 2012..Sat, 30 Jun 2012
1.month.ago.beginning_of_month.to_date.succ
# => Sat, 02 Jun 2012

Используйте to_date для преобразования ActiveSupport::TimeWithZone в Date.

(1.month.ago.beginning_of_month.to_date..1.month.ago.end_of_month.to_date).
  each do |day| 
    p day
  end

Это будет повторяться в течение нескольких дней в прошлом месяце.

Оказывается, что проблема заключается в использовании метода succ на ActiveSupport::TimeWithZone, который вызывает Time#succ is obsolete предупреждения.