【问题标题】:Comparing ranges of datetimes in Ruby on Rails against one-another比较 Ruby on Rails 中的日期时间范围
【发布时间】:2014-08-13 05:37:40
【问题描述】:

现在我正在尝试查看某个节目的开始和结束时间是否与另一个正在录制的节目重叠 => 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 节目的 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)

这给了我错误,即使时间完全相同。如何将重叠时间与节目列表进行比较,以找出导致重叠的节目?

【问题讨论】:

    标签: ruby-on-rails ruby


    【解决方案1】:

    你会想签出:

    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
    

    【讨论】:

      【解决方案2】:

      这是一个很常见的问题,我建议您查看这个 SO question,了解有关如何进行重叠检查的一般算法建议:

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

      【讨论】:

      • 那么您是否建议将代码重组为类似于第一个答案here - 因为重叠检查当前有效,它只是找出哪个节目对象导致它出现在节目数组中并拉动在那个节目中,因为现在它只有来自该数组的日期时间导致它,并且比较日期时间即使它们相同也会返回错误
      • 啊,我误解了你的问题。我基本上会使用更通用的循环结构;让我更新我的答案
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-17
      • 1970-01-01
      • 2015-10-01
      • 1970-01-01
      相关资源
      最近更新 更多