2012-05-03 126 views
15

我正在處理用戶輸入日期範圍並從複選框列表中選擇星期幾,星期一,星期二,星期三,星期四,星期五和星期六的星期幾/星期幾的表單。如何獲取Ruby中兩個日期之間的所有星期日?

提交表格後,我需要一種方法來根據選定日期(即所有星期一和星期四所給出的日期)獲取所輸入的兩個日期之間的日期列表。我瀏覽過文檔,但不能指出如何有效地實現這一點,即紅寶石的方式。

回答

46

有趣的一個! :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)} 

使用上面的數據,您將在現在和明年之間獲得所有星期/星期二/星期六的數組。

+1

真棒:d謝謝!現在看起來像它應該如何在ruby中完成! – Ali

+1

我只建議在這裏使用'to_enum'而不是'to_a'。 –

+0

它不太可能是有限的。我仍然選擇數組,因爲大小(天數)可能會受到質疑等。 – TomDunning

0

以上答案在邏輯上是正確的,但需要更多時間,我做了一些基準測試,這裏是區別。

第二種方法的執行時間非常短。

克隆上述程序的:

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 " 
+0

做得好@A H K,真棒。 – 2015-09-15 22:52:59

+2

只需指出顯而易見的情況:「2015/10/03」和「4037/11/30」之間不存在5個星期五。如果您對5周的數據集運行我的代碼,它的性能將與您的代碼一樣快。它也會返回日期,而不是計數,這就是問題所要求的。請你可以用與輸入相匹配的輸出更新你的答案嗎?我一直在尋找更好的解決方案! – TomDunning

+0

當您在is_there_any_friday方法中進行迭代並找到星期五時,您應該會中斷。 – brianfalah

4

另一種方法是將你的日期範圍內按wday,並挑選了你一週中的哪一天:

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

例如,讓所有周日在2016年3月:

> (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] 
相關問題