简体   繁体   中英

Comparing ranges of datetimes in Ruby on Rails against one-another

Right now I'm trying to see if a certain show's start and end times overlap another show that's currently recording => true where 'show' is the TV show the user wants to record.

  def self.record_show
    shows = Box.first.shows.where(:recording => true).flatten
    show_start_and_end_times = shows.collect {|x| x.start_time..x.end_time}
    current_show_time = show.start_time..show.end_time
    overlap = show_start_and_end_times.select {|c| current_show_time.overlaps?(c)}

    if overlap.present?
      nil
    else
      show.update_attributes(:recording => true)
      show.save
    end
  end

It runs the method, but I'm having difficulty figuring out how to get it so that it finds the actual currently recording show that's causing the overlap. So for example, let's say in 'shows' I currently have two shows:

[#<Show id: 181, box_id: 78, title: "The Fox", channel: 22, single_recording: true, created_at: "2014-08-12 19:55:49", updated_at: "2014-08-12 20:09:24", start_time: "2014-08-12 19:55:49", end_time: "2014-08-12 20:25:49", recording: true>, #<Show id: 186, box_id: 78, title: "Funniest Home Videos", channel: 45, single_recording: true, created_at: "2014-08-12 19:55:49", updated_at: "2014-08-12 20:09:27", start_time: "2014-08-12 23:20:49", end_time: "2014-08-13 00:20:49", recording: true>] 

In show_start_and_end_times I have:

[Tue, 12 Aug 2014 19:55:49 UTC +00:00..Tue, 12 Aug 2014 20:25:49 UTC +00:00, Tue, 12 Aug 2014 23:20:49 UTC +00:00..Wed, 13 Aug 2014 00:20:49 UTC +00:00] 

In current_show_time I have:

Tue, 12 Aug 2014 19:55:49 UTC +00:00..Tue, 12 Aug 2014 20:55:49 UTC +00:00 

Which means that in overlap I have the start_time..end_time of the first show_start_and_end_times show, which is the one that is causing the overlap:

[Tue, 12 Aug 2014 19:55:49 UTC +00:00..Tue, 12 Aug 2014 20:25:49 UTC +00:00] 

I tried comparing the two times against one-another:

(shows.first.start_time..shows.first.end_time) == (overlap.first)

Which gives me false, even though the times are exactly the same. How can I compare the overlap time against the shows list to figure out which show is causing the overlap?

This is a pretty common problem, and I'd recommend checking out this SO question for general algorithm advice on how to do the overlap checking:

Determine Whether Two Date Ranges Overlap

UPDATE:

I would change it to something like this:

shows = Box.first.shows.where(:recording => true).flatten
overlapping_show = nil
current_show_time = show.start_time..show.end_time
shows.each do |s|
  if current_show_time.overlaps?(s.start_time..s.end_time)}
    overlapping_show = s
    break  # you could alternatively return an array of overlapping
           # if you anticipate more than 1 will overlap
  end
end

if overlap.present?  #...

You'll wand to check out:

http://guides.rubyonrails.org/active_record_querying.html

Using info from that you might be able to do something like:

def self.record_show
  overlapping_shows = Box.first.shows.where(recording: true).where("start_time <= :show_end AND end_time >= :show_start", {show_start: show.start_time, show_end: show.end_time}).flatten

  if overlapping_shows.present?
    nil
  else
    show.update_attributes(:recording => true)
    show.save
  end
end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM