检查一个时间范围是否在另一个时间范围和Ruby on Rails多少小时之间

时间:2019-01-23 15:33:16

标签: ruby-on-rails ruby datetime ruby-on-rails-5

所以我有一个开始时间和结束时间。最多24小时。 我想我首先需要检查此时间范围是否在另一个时间范围内,例如21:00-01:00。如果是,我需要知道在时间范围内有多少小时。 有什么想法吗?

5 个答案:

答案 0 :(得分:0)

使用((二合一)/ 3600)。回合

例如

one=Time.now #=>2019-01-23 21:19:19 +0530
two=Time.now + 1*60*60 #=>2019-01-23 22:19:27 +0530
((two- one) / 3600).round #=>1 

两个不同的Time实例的差异为1小时。

答案 1 :(得分:0)

我假定下面方法的四个参数是形式为“ HH:MM”或“ HH:MM:SS”的字符串。我提供了一个纯Ruby解决方案,该解决方案仅进行字符串比较(例如:"17:26" < "18:00" #=> true)。也就是说,我不会将字符串转换为Time对象。

def time_within_ref?(time_start, time_end, ref_start, ref_end)
  (time_start >= ref_start) &&
  (adj_hour(time_start, time_end) <= adj_hour(ref_start, ref_end))
end

def adj_hour(start_str, end_str)
  end_str[0,2] = (end_str[0,2].to_i + 24).to_s if end_str < start_str
  end_str
end

以下是一些示例。

time_within_ref?("19:00", "02:00", "18:00", "03:00")
  #=> true 
time_within_ref?("19:00", "04:00", "18:00", "03:00")
  #=> false
time_within_ref?("17:00", "02:00", "18:00", "03:00")
  #=> false
time_within_ref?("18:00", "02:00", "18:00", "03:00")
  #=> true

答案 2 :(得分:0)

“内”是什么意思?您是否要测试范围之间是否存在重叠,或者第一个范围是否完全包含在另一个范围内?

您可以使用范围内的Time对象并利用#cover?来检查重叠

start_time = 5.hours.ago
end_time = 4.hours.ago

check_range_start = (4.5).hours.ago
check_range_end = (3.5).hours.ago
check_range = (check_range_start..check_range_end)

check_range.cover?(end_time)   # => true
check_range.cover?(start_time) # =>false

如果检查范围覆盖了范围的两端,那么您的范围将被完全覆盖。如果只覆盖一端,则说明您有重叠。如果两端都没有覆盖,则范围不会相交。

一旦知道是否存在交集,就可以轻松计算出时间范围的一端到检查范围的一端的距离;如果您想知道检查范围开始与输入开始时间之间有多长时间,只需减去start_time - check_range_start

答案 3 :(得分:0)

在数据库中执行此操作的方法有多种,它们比将一堆记录加载到Rails中的性能要好得多。

尽管“纯红宝石”解决方案是一种快速解决方案,但在记录量不小的情况下,它们将耗尽可用内存并使服务器崩溃。

您可以将范围与.where一起使用以创建WHERE start_time BETWEEN a AND b子句,以确保时间在A和B之内。

starts_today = Model.where(
  start_time: Time.current.beginning_of_day..Time.current.end_of_day
)

如果要确保start_timeend_time之间的整个范围都在一定范围内,则可以编写自己的where子句:

Model.where(
  "start_time > :a AND end_time < :b", 
  a: Time.current.beginning_of_day, 
  b: Time.current.end_of_day
)
  

我需要知道在该时间范围内有多少小时。

您可以使用数据库中的时间/日期功能来执行此操作。 例如,在postgres上,您可以执行以下操作:

bounds = Time.current.beginning_of_day..Time.current.end_of_day
Model.select(
  "models.*,  (EXTRACT(HOUR FROM end_time - start_time ) - EXTRACT(HOUR FROM end_time - '#{ bounds.end.iso8601 }')) AS number_of_hours"
)

例如,如果您想在WHERE子句中使用它,则再次在数据库中计算该值至关重要。

答案 4 :(得分:0)

我想我明白了。 Shift.start_time.strftime("%H:%M") => '20:00' && Shift.end_time.strftime("%H:%M") <= '01:00' .to_time弄乱了我,也影响了订购。

相关问题