Reputation: 279
I generated a table called DimensionDate
, which contains all dates between 2011,12,31 and 2032,1,1 .
Now, I would like to know the absolute range of a month between these two dates, for each date.
For example :
2012-01-01 is the number 1 month
2012-02-01 is the number 2 month
2013-01-01 is the number 13 month
2013-02-01 is the number 14 month
2014-01-01 is the number 25 month
2014-02-01 is the number 26 month
etc...
How could I do that ? Any Idea ? Thanks for your help
Upvotes: 1
Views: 1338
Reputation: 13921
Something like this?
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
Edit:
As a bonus here is a version with a default value if you know you will always compare with a specific date. The logic is the same, just short instead of readable:
# 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:
As dax pointed out my function do not provide any form of validation, here is how you would implement that:
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.
Upvotes: 6
Reputation: 11007
Hirolau's answer is good but I think this can be made simpler/error proofed. Since the start time is absolute, you don't need to include it in the method's arguments. You can test it against the end time as well:
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
tested:
$ 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!"
Upvotes: 1