查找Ruby on Rails中两个日期之间的月数

时间:2012-02-24 09:48:27

标签: ruby-on-rails ruby date ruby-on-rails-3.1

我有两个Ruby on Rails DateTime对象。如何查找它们之间的月数? (请记住,他们可能属于不同年份)

13 个答案:

答案 0 :(得分:155)

(date2.year * 12 + date2.month) - (date1.year * 12 + date1.month)

http://www.ruby-forum.com/topic/72120

的更多信息

答案 1 :(得分:39)

更准确的答案会考虑远处的天数。

例如,如果您认为28/4/20001/5/2000的月距离是0而不是1,那么您可以使用:

(date2.year - date1.year) * 12 + date2.month - date1.month - (date2.day >= date1.day ? 0 : 1)

答案 2 :(得分:14)

尝试

((date2.to_time - date1.to_time)/1.month.second).to_i

答案 3 :(得分:8)

您可以将问题重新定义为"日期和#34;的月份开始之间有多少第1天,然后使用功能样式的数据转换:

(date1.beginning_of_month...date2.beginning_of_month).select { |date| date.day == 1 }.size

答案 4 :(得分:5)

假设两者都是日期: ((date2 - date1).to_f / 365 * 12).round 简单。

答案 5 :(得分:2)

我发现的另一个解决方案(建立在此处发布的解决方案)是为了您希望结果包含一个月的分数。例如,距离为1.2 months

((date2.to_time - date1.to_time)/1.month.second).round(1) #Tenth of a month Ex: 1.2
((date2.to_time - date1.to_time)/1.month.second).round(2) #Hundreth, ex: 1.23 months
etc...

答案 6 :(得分:2)

start_date = Date.today
end_date   = Date.today+90
months = (end_date.month+end_date.year*12) - (start_date.month+start_date.year*12)

//months = 3

答案 7 :(得分:2)

def difference_in_months(date1, date2)
  month_count = (date2.year == date1.year) ? (date2.month - date1.month) : (12 - date1.month + date2.month)
  month_count = (date2.year == date1.year) ? (month_count + 1) : (((date2.year - date1.year - 1 ) * 12) + (month_count + 1))
  month_count
end

答案 8 :(得分:1)

这是蛮力强迫的变种:

date1 = '2016-01-05'.to_date
date2 = '2017-02-27'.to_date
months = 0

months += 1 while (date2 << (count+1)) >= date1
puts months # => 13

date2必须始终大于date1

答案 9 :(得分:0)

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

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

答案 10 :(得分:0)

这是另一种方法。这将有助于计算两个日期之间的整个月数

def months_difference(date_time_start, date_time_end)
  curr_months = 0
  while (date_time_start + curr_months.months) < date_time_end
    curr_months += 1
  end
  curr_months -= 1 if (date_time_start + curr_months.months) > date_time_end
  curr_months.negative? ? 0 : curr_months
end

答案 11 :(得分:0)

任何情况下的解决方案

(date1..date2).map { |date| date.strftime('%m.%Y') }.uniq.size

答案 12 :(得分:0)

这个怎么样?我发现它很干净

((date2 - date1) / 1.month).round