Проверьте, находится ли временной диапазон между другим временным диапазоном и сколько часов Ruby on Rails - PullRequest
0 голосов
/ 23 января 2019

Итак, у меня есть start_time и end_time. Что максимум 24 часа. Я предполагаю, что сначала мне нужно проверить, находится ли этот временной диапазон в другом временном диапазоне, скажем, 21: 00-01: 00. Если это так, мне нужно знать, сколько часов находится во временном интервале. Есть идеи?

Ответы [ 5 ]

0 голосов
/ 24 января 2019

Думаю, я понял это.Shift.start_time.strftime("%H:%M") => '20:00' && Shift.end_time.strftime("%H:%M") <= '01:00' .to_time связывался со мной и с заказом.

0 голосов
/ 24 января 2019

Есть несколько способов сделать это в базе данных, которые гораздо более производительны, чем загрузка нескольких записей в 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_time и end_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.

0 голосов
/ 23 января 2019

Я предполагаю, что четыре аргумента метода, приведенного ниже, представляют собой строки в формате «ЧЧ: ММ» или «ЧЧ: ММ: СС». Я предоставил решение на чистом 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
0 голосов
/ 23 января 2019

Что вы подразумеваете под "внутри"? Вы имеете в виду, что хотите проверить, нет ли какого-либо перекрытия между диапазонами или первый диапазон полностью содержится в другом?

Вы можете использовать объекты 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.

0 голосов
/ 23 января 2019

Использование ((два-один) / 3600) .round

например

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 

разница составляет 1 час для двух разных экземпляров времени.

...