Как получить все воскресенья между двумя датами в 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 "