比较Ruby on Rails中的日期时间范围

时间:2014-08-12 21:01:15

标签: ruby-on-rails ruby

现在我正在尝试查看某个节目的开始和结束时间是否与当前正在录制的另一个节目重叠=>如果'show'是用户想要录制的电视节目,则为true。

  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

它运行该方法,但我很难弄清楚如何获取它,以便它找到导致重叠的实际当前录制节目。例如,让我们说'节目'我目前有两个节目:

[#<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>] 

在show_start_and_end_times中我有:

[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] 

在current_show_time中,我有:

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

这意味着在重叠中我有第一个show_start_and_end_times show的start_time..end_time,这是引起重叠的那个:

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

我尝试将这两次相互比较:

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

即使时间完全相同,这也是假的。如何将重叠时间与节目列表进行比较,以确定哪个节目导致重叠?

2 个答案:

答案 0 :(得分:0)

这是一个非常常见的问题,我建议查看这个SO问题,以获取有关如何进行重叠检查的一般算法建议:

Determine Whether Two Date Ranges Overlap

更新:

我会把它改成这样的东西:

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?  #...

答案 1 :(得分:0)

你会用魔杖看看:

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

使用您可以执行以下操作的信息:

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