Ruby - 获取两个日期之间的月份范围

时间:2013-10-14 11:48:00

标签: ruby-on-rails ruby date

我生成了一个名为DimensionDate的表,其中包含2011,12,31和2032,1,1之间的所有日期。

现在,我想知道这两个日期之间每个日期的绝对范围。

例如:

2012-01-01是1个月的数字

2012-02-01是2个月的数字

2013-01-01是13个月的数字

2013-02-01是14个月的数字

2014-01-01是25个月的数字

2014-02-01是26个月的数字

等...

我怎么能这样做?任何的想法 ? 谢谢你的帮助

2 个答案:

答案 0 :(得分:6)

这样的东西?

require 'date'

def months_between_dates(date_1, date_2)
  diff_in_years  = (date_1.year-date_2.year)*12
  diff_in_months = date_1.month-date_2.month
  return (diff_in_years + diff_in_months).abs
end

start_date  = Date.new(2011,12,31)
test_date   = Date.new(2013,01,01)
test_date_2 = Date.new(2014,02,01)

p months_between_dates(start_date, test_date)   # => 13
p months_between_dates(start_date, test_date_2) # => 26

编辑:

如果您知道自己将始终与特定日期进行比较,则此处的奖励是具有默认值的版本。逻辑是相同的,只是简短而不是可读:

# Call by passing one or two dates:
def delta_months(x, y=Date.new(2011,12,31))
  ((x.year-y.year)*12+(x.month-y.month)).abs 
end

p delta_months(test_date)  # => 13

EDIT2:

正如dax指出我的功能不提供任何形式的验证,以下是如何实现:

MIN_DATE, MAX_DATE = Date.new(2011,12,31), Date.new(2032,1,1)
date_range = MIN_DATE..MAX_DATE
test_date  = Date.new(2064,1,1)

raise "Date out of range, must be between #{MIN_DATE} and #{MAX_DATE}." unless date_range.cover? test_date # => Date out of range, must be between 2011-12-31 and 2032-01-01. (RuntimeError)
delta_months(test_date)  # Never called unless good date is provided.

答案 1 :(得分:1)

Hirolau的答案很好,但我认为这可以更简单/防错。由于开始时间是绝对的,因此您无需将其包含在方法的参数中。您也可以在结束时间内对其进行测试:

def dimensional_date_range(now)
  range = (now.year - 2012)*12 + (now.month)
  if range <= 240 
    range
  else
    "you're out of this dimension, man!"
  end
end

测试:

$ date =  Date.new(2014,02,01)
$ date2 = Date.new(2050,01,01)
$ dimensional_date_range(date)
 => 26
$ dimensional_date_range(date2)
 => "you're out of this dimension, man!"