Как получить все воскресенья между двумя датами в Ruby?

Я работаю над формой, в которой пользователь вводит диапазон дат и выбирает из списка флажков день/дни недели, а именно: воскресенье, понедельник, вторник, среду, четверг, пятницу и субботу.

Как только форма будет отправлена, мне нужен способ захватить список дат между двумя датами, введенными в зависимости от дней, которые были выбраны. Все понедельники и четверги между двумя датами. Я просмотрел документы, но не могу указать, как это сделать эффективно, но это рубиновый путь.

Ответы

Ответ 1

веселый!: D

 start_date = Date.today # your start
 end_date = Date.today + 1.year # your end
 my_days = [1,2,3] # day of the week in 0-6. Sunday is day-of-week 0; Saturday is day-of-week 6.
 result = (start_date..end_date).to_a.select {|k| my_days.include?(k.wday)}

используя приведенные выше данные, вы получите массив всех Mon/Tue/Weds между настоящим и следующим годом.

Ответ 2

Другой подход - группировать диапазон дат на wday и выбирать день недели:

datesByWeekday = (start_date..end_date).group_by(&:wday)
datesByWeekday[6] # All Sundays

например, чтобы получить все воскресенья в марте 2016 года:

> (Date.new(2016,03,01)..Date.new(2016,04,01)).group_by(&:wday)[6]
=> [Sat, 05 Mar 2016, Sat, 12 Mar 2016, Sat, 19 Mar 2016, Sat, 26 Mar 2016] 

Ответ 3

Выше ответ логически корректен, но занимает больше времени, я сделал некоторый бенчмаркинг, и вот разница.

Время выполнения второго подхода очень мало.

Клон вышеуказанной программы:

def check_fridays(d1, d2)
 my_days = [5]
 (Date.parse(d1)..Date.parse(d2)).to_a.select { |k| my_days.include?(k.wday) }
end

start_time = Time.now();
fridays = check_fridays("2015/10/03", "4037/11/30")
endtime = Time.now();

p "Time Taken #{(endtime - start_time) * 1000.0}"

p "There are #{fridays.length} Fridays "

Выход

"Time Taken 486.922"
"There are 105511 Fridays "

Второй подход:

require 'date'

def check_fridays(d1, d2)

  # Compare the input values and swap accordingly
  d1p = d1 <= d2 ? Date.parse(d1) : Date.parse(d2)
  d2p = d2 >= d1 ? Date.parse(d2) : Date.parse(d1)

  # Total Number Days
  number_of_days = (d2p-d1p).to_i

  # Total Number Of Weeks
  total_weeks = number_of_days/7

  # Get The Reminder For Friday Check
  remaining_days = number_of_days%7

  # Check if any friday lies in remaining days
  if is_there_any_friday(remaining_days, d1p, d2p)
    total_weeks += 1
  end

  #Return The Total No Of Fridays
  total_weeks
end

def is_there_any_friday(remaining_days, start_date, end_date)
  got_friday = false #First set variable as false

  #First check from start date
  (0..remaining_days).each do |i|
    got_friday = (start_date+i).friday?
  end

  # If There Is No Friday Found In Start Date
  unless got_friday
    (0..remaining_days).each do |i|
      got_friday = (end_date-i).friday?
    end
  end

  #Return True OR False
  got_friday
end

start_time = Time.now()
fridays = check_fridays("2015/10/03", "4037/11/30")
end_time = Time.now()

p "Time Taken #{(end_time - start_time) * 1000.0}"

p "There are #{fridays} Fridays "

Выход

"Time Taken 0.754"
"There are 105511 Fridays "