2013-10-14 196 views
1

我生成了一個名爲DimensionDate的表,其中包含2011,12,31和2032,1,1之間的所有日期。紅寶石 - 獲取兩個日期之間的月份範圍

現在,我想知道這兩個日期之間每月的絕對範圍。

例如:

2012-01-01是數字1個月

2012-02-01是數字2個月

2013-01-01是數13個月

2013年2月1日是多少14個月

2014年1月1日被數25個月

2014年2月1日是每月的26號

等等

我怎麼能這樣做呢?任何想法 ? 感謝您的幫助

回答

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. 
+0

非常感謝你爲這個完美的答案。一切工作就像它應該! –

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!" 
+0

我試圖讓我的功能儘可能一般,我覺得你的版本有三個缺點。 1:數字240在代碼中沒有解釋,並且如果/當範圍在將來發生變化時,將很難找出爲什麼以及如何更改240。 2:有效範圍的測試返回一個字符串而不是引發錯誤。 3:測試沒有考慮低於最小日期的值,因此如果低於最小值的日期在函數中傳遞,則返回值而不是引發錯誤。 – hirolau

+1

夠公平 - 我給你+1了,我覺得你的回答很好。只是提供其他選項。你也提出了很好的觀點,所以謝謝:) – dax