Reputation: 32945
I'm trying to find a way to neaten this up. I have a collection of License records, loaded already from data. Each has a start_date and end_date field. I want to select
those that cross a given date, in any year. (when i say they cross that date, i mean start_date is before the date and end_date is after the date).
Here's the clunky way i'm doing it at the moment, which uses an array of that same date in different years, going back 10 years and forward 10 years.
target_date = Date.parse("30-09-2015")
date = target_date - 10.years
dates = []
while date < 10.years.from_now
dates << date
date += 1.year
end
#now have an array `dates` of Date objects holding eg ["30-09-2005", 30-09-2006", ... "30-09-2025"]
crossing_licenses = licenses.select{|license| dates.detect{|date| license.start_date < date && license.end_date > date}}
This works but it feels like there must be a much more elegant way to do it. Thanks, Max
PLEASE NOTE: i start with the collection of licenses already, and so i'm NOT looking for how to do an sql query to get these licenses.
EDIT: potential gotcha - watch out for a licence starting the previous year, eg that goes from "10-10-2014" to "30-10-2015".
Upvotes: 0
Views: 139
Reputation: 4015
I would say that you don't need an array with dates to do this:
target_date = Date.parse("30-09-2015")
crossing_licenses = licenses.select do |license|
return false if license.end_date < 10.years.ago
return false if license.start_date > 10.from_now
(license.start_date..license.end_date).any? do |date|
date.month == target_date.month && date.day == target_date.day
end
end
Just make sure, that the start_date
and end_date
are actually Date
objects, and not Time
. If so, it is better to convert them to dates, otherwise you will get huge ranges.
Upvotes: 1