Rails以月为单位计算日期范围

如何计算两个月的差异? 此外,它有所作为,我正在使用Date对象,而不是DateTime。 此外,一些舍入选项可能会很好,所以我可以控制是否要在部分月份上舍入或下舍入。

谢谢!

从另一个日期或日期时间中减去一个日期或日期时间将产生作为分数的天数,但可以根据需要将其评估为FloatFixnum

例如:

 (Date.today - Date.today.advance(:months => -3)).to_f # => 89.0 

从今天到三个月前的同一日历日期之间有89.0天。 如果你使用平均30天或30.4375这样做,你最终会在当时和现在之间经过2.92个月,或者向上舍入到最接近的整数3。

如果您想计算精确的日历月数,那就更难了,但可以完成。

这应该给出一个很好的近似值:

 Date1 - Date2 = difference_in_days (difference_in_days/30).round = difference_in_months 

像这样的东西比计算秒数更具可读性,并且会给你实际的日历差异:

 # Calculate differnce between two dates in months # Produces b - a def month_difference(a, b) difference = 0.0 if a.year != b.year difference += 12 * (b.year - a.year) end difference + b.month - a.month end 

如果您还需要根据天数计算差异,您可以按照模式进行操作

我们需要这些方面的东西,但包括部分月份。 所以1/31到2/1仍然会产生2个月。 可能有帮助!

 def self.month_count(range) 12 * (range.end.year - range.begin.year) + range.end.month - range.begin.month end 

这个答案迟到了,以前面的答案为基础,并且可能写得更简洁,但是,它确实给出了考虑几天的两个日期之间的日历差异。

 def difference_in_months(start_date, today) date_to_months(today) - date_to_months(start_date) + adjustment_for_days(start_date, today) end def date_to_months(date) date.year * 12 + date.month end def adjustment_for_days(earlier_date, later_date) if later_date.day == earlier_date.day 0 elsif later_date.day > earlier_date.day 1 else -1 end end 

这种做法怎么样?

 current_date = start_date while current_date < end_date # something current_date = current_date.next_month end 

我需要两个日期之间的确切月数(包括小数),并为它编写了以下方法。

 def months_difference(period_start, period_end) period_end = period_end + 1.day months = (period_end.year - period_start.year) * 12 + period_end.month - period_start.month - (period_end.day >= period_start.day ? 0 : 1) remains = period_end - (period_start + months.month) (months + remains/period_end.end_of_month.day).to_f.round(2) end 

如果比较让我们说9月26日到9月26日(同一天)我计算为1天。 如果您不需要,可以删除方法中的第一行: period_end = period_end + 1.day

它通过以下规范:

 expect(months_difference(Date.new(2017, 8, 1), Date.new(2017, 8, 31))).to eq 1.0 expect(months_difference(Date.new(2017, 8, 1), Date.new(2017, 8, 30))).to eq 0.97 expect(months_difference(Date.new(2017, 8, 1), Date.new(2017, 10, 31))).to eq 3.0 # Overlapping february (28 days) still counts Feb as a full month expect(months_difference(Date.new(2017, 1, 1), Date.new(2017, 3, 31))).to eq 3.0 expect(months_difference(Date.new(2017, 2, 10), Date.new(2017, 3, 9))).to eq 1.0 # Leap year expect(months_difference(Date.new(2016, 2, 1), Date.new(2016, 2, 29))).to eq 1.0 

它依赖于Rails的ActiveSupport。

Interesting Posts