legendary_rob
legendary_rob

Reputation: 13012

Rails, counting months in date range, between date ranges

This has been quite a mission so far. What i am trying to do is find out how many months there are for a date range between two date ranges.. i know i sound like Yoda right now but let me rather show you what i am trying to accomplish.

financial_year_2014 = Date.new(2014,6,29)..Date.new(2015,6,30) 
financial_year_2015 = Date.new(2015,6,29)..Date.new(2016,6,30)

Now i have a scorecard that awards 1 point per month you are in the financial_year_2014, and 2 points per month you are in the financial_year_2015

So if your Scorecards begin_date and end_date both fall within the financial_year_2014 its easier where you can do something like this

#Does date fall in range method
financial_year_2014.include?(scorecard.begin_date..scorecard.end_date)

Which would then return true if it fit within that period, then you could count the months with:

((scorecard.end_date.year * 12 + scorecard.end_date.month) - (scorecard.begin_date.year * 12 + scorecard.begin_date.month)) * financial_year_2014_points

But now what i can't get is if a scorecards begin_date and end_date cross between two financial years, if the begin_date was May and the end_date was in August. Then you would have 2 Months in the 2014 financial year and 2 months in the 2015 year. You would then be awarded 1 point for each month in 2014 and 2 points for each month in 2015, for a total of 6 in this example.

The #does date fall in range method with the above example won't pass either even though 2 months fall within the range.. Any one have an idea to how i could get this done, or if there is any gem that handles dates and ranges like this better.

Upvotes: 1

Views: 1463

Answers (2)

Paulo Fidalgo
Paulo Fidalgo

Reputation: 22331

You can check the months within a date range like this:

require 'date'
((Date.today - 90)..Date.today).map{|d| [d.month]}.uniq

To check if a range include another range you can use this:

a = ((Date.today - 90)..Date.today)
b = ((Date.today-10)..(Date.today-5))
(a.to_a & b.to_a).empty? # false if includes

Just be aware that it will compare every member of the Range.

Upvotes: 2

MCBama
MCBama

Reputation: 1490

Well I'm not 100% sure of how your code is set up but I would have just done something like this:

if financial_year_2014.include?(scorecard.begin_date..scorecard.end_date) || financial_year_2015.include?(scorecard.begin_date..scorecard.end_date)
  #calculate based on 2014/2015 year only
else
  #calculate based on split between the years
  range_one = scorecard.begin_date..Date.new(2015,6,30)
  range_two = Date.new(2015,6,30)..scorecard.end_date
  #use new ranges to calculate 
end

Upvotes: 1

Related Questions