In ruby, given two date ranges, I want the range that represents the intersection of the two date ranges, or nil if no intersection. For example:
(Date.new(2011,1,1)..Date.new(2011,1,15)) & (Date.new(2011,1,10)..Date.new(2011,2,15))
=> Mon, 10 Jan 2011..Sat, 15 Jan 2011
Edit: Should have said that I want it to work for DateTime as well, so interval can be down to mins and secs:
(DateTime.new(2011,1,1,22,45)..Date.new(2011,2,15)) & (Date.new(2011,1,1)..Date.new(2011,2,15))
=> Sat, 01 Jan 2011 22:45:00 +0000..Tue, 15 Feb 2011
I'd transfer them into an array, since arrays know the intersection-operation:
Of course this returns an Array. So if you want an Enumerator (Range doesn't seem to be possible since these are not consecutive values anymore) just throw
to_enum
at the end.Try something like this
What this will give you is a array of intersection dates!!
I have times as
[[start, end], ...]
and I want to remove the some time ranges from a each initial time range, here is what I did:You can try this to get a range representing intersection
Converting your example:
I found this: http://www.postal-code.com/binarycode/2009/06/06/better-range-intersection-in-ruby/ which is a pretty good start, but does not work for dates. I've tweaked a bit into this:
I've omitted the tests, but they are basically the tests from the post above changed for dates. This works for ruby 1.9.2.
Anyone got a better solution?
I baked this solution for ascending ranges, also taking care of the exclude end situations:
I'm also a bit worried by you guys adding it to the Range class itself, since the behavior of intersecting ranges is not uniformly defined. (How about intersecting 1...4 and 4...1? Why nil when there is no intersection; we could also say this is an empty range: 1...1 )