/ / отримати десяткову кількість місяців для діапазону дат - рубін, дата, різниця

отримати десяткове число місяців для діапазону дат - ruby, date, diff

Я намагаюся отримати десяткову кількість місяців для діапазону дат. Приклад:

ruby-1.9.2-p0 > from = Date.new(2011, 7, 6)
=> Wed, 06 Jul 2011
ruby-1.9.2-p0 > to = Date.new(2011, 8, 31)
=> Wed, 31 Aug 2011
ruby-1.9.2-p0 > to - from
=> (56/1)

Тож різниця становить 56 днів. Але мені потрібна і потрібна кількість місяців: 1,83

Я створив наступний фрагмент коду, який повертає правильний результат, але не відчуває себе схожим на рубіновий:

months = Hash.new
(from..to).each do |date|
unless months.key? date.beginning_of_month
months[date.beginning_of_month] = 1
else
months[date.beginning_of_month] += 1
end
end

multiplicator = 0.0
months.each do |month, days|
multiplicator += days.to_f/month.end_of_month.day
end

return multiplicator.floor_to(2)

Чесно кажучи: це виглядає потворно і насправді неефективно. Але я просто не можу зрозуміти простішого способу. Чи можете ви допомогти мені знайти краще рішення?

Для подальших питань сміливо задавайте мені.

Велике спасибі заранее!


Оновлення / рішення: Вирішено проблему з таким фрагментом коду:

months = 0.0

months += ((date_to < date_from.end_of_month ? date_to : date_from.end_of_month) - date_from + 1) / Time.days_in_month(date_from.month)
unless date_to.month == date_from.month
months += (date_to - date_to.beginning_of_month + 1) / Time.days_in_month(date_to.month)
months += date_to.month - date_from.month - 1
end

return months.floor_to(2)

Відповіді:

1 для відповіді № 1

кращим способом буде підсумовування

  • кількість днів, що залишились у від / кількість днів у з
  • кількість днів, виконаних у до / кількість днів у до
  • кількість місяців між і з (з, до виключено)

Таким чином у вас не буде ітерацій