2016-04-20 61 views
2

如果用戶使用days_challenge: 5 & committed: ["mon", "tue", "wed", "thu", "fri"]創建一個質詢,那麼我們如何使用名爲dates_challenged的模型方法創建一個從date_started: "2016-04-20"到日期最後一天的日期數組?如何將整數轉換爲日期數組?

create_table "challenges", force: true do |t| 
    t.string "action" 
    t.date  "date_started" 
    t.text  "committed",  default: "---\n- sun\n- mon\n- tue\n- wed\n- thu\n- fri\n- sat\n" 
    t.integer "days_challenged" 
end 

的陣列會是這個樣子:["2016-04-20", "2016-04-21", "2016-04-22", "2016-04-25", "2016-04-26"]

class Challenge < ActiveRecord::Base 
    serialize :committed, Array 

    def dates_challenged 
    # Not sure if a model method is enough or if I'd have to migrate a new column 
    end 

    def committed_wdays 
    committed.map do |day|  
     Date::ABBR_DAYNAMES.index(day.titleize) 
    end 
    end 

    def days_left_challenged 
    def days_done_challenged 
     ((date_started.to_date)..Date.yesterday).count do |date| 
     committed_wdays.include? date.wday 
     end 
    end 
    if self.days_done_challenged >= self.days_challenged 
     0 
    else 
     self.days_challenged - ((date_started.to_date)..Date.yesterday).count do |date| 
     committed_wdays.include? date.wday 
     end 
    end 
    end 
end 

爲了澄清,我試圖做一個模型的方法,所以我可以在一個視圖中,我可以然後遍歷做@challenge.dates_challenged日期數組。

回答

2

這是我想出了 - 仍存在一些問題 - 我認爲這將炸燬,如果committed是空的,但它是很好的,簡潔的:在的複雜性

def dates_challenged 
    date = date_started-1 
    days_challenge.times.map { date = find_next(date) } 
end 

private 
def find_next(date) 
    break if committed.include? Date::ABBR_DAYNAMES[date.wday].downcase while date = date.next 
    date 
end 
0

獲取的開始日期和結束日期 - 那麼你可以得到一個日期範圍和或開始和結束

start_date = challenge.date.to_date 
end_date = another_challenge.date.to_date 
(start_date..end_date).map(&:mday) # returns array of days of the month 

看到List Array of Days Between Two Dates以獲取更多信息之間的天

+0

部分問題是你如何得到結束日期?不過謝謝,如果我能夠自己創建方法,使用信息作爲答案,我會給你信用:] –

+0

你想要最新的日期的挑戰嗎? – lfender6445

+0

我正在嘗試使用'dates_challenged'方法創建一個日期數組。我舉例說明如果'date_started'是今天,'days_challenged'是5,'committed'是工作日,會輸出什麼。希望更清楚。抱歉不太清楚你的問題。 –

0
committed = ["mon", "tue", "wed", "thu", "fri"] 
days = committed.dup 

count = 0 
dates = [] 

while days.present? 
    count += 1 
    weekday = (date + count).strftime('%a').downcase 
    if days.include? weekday 
     dates << (date + count.days).strftime('%Y-%m-%d') 
     days.delete(weekday) 
    end 
end 

puts dates # => ["2016-04-21", "2016-04-22", "2016-04-25", "2016-04-26", "2016-04-27"] 

上一個回答

假設你是在Rails環境:

days_challenge = 5 
date   = DateTime.parse("2016-04-20") 

(1..days_challenge).map {|n| (date + n.days).strftime('%Y-%m-%d') } 

# Outputs 
["2016-04-21", "2016-04-22", "2016-04-23", "2016-04-24", "2016-04-25"] 
+0

是的,我試圖在rails中創建一個'dates_challenged'方法。感謝您試圖再次幫助我。問題與輸出雖然。這表明連續5天。我給出的例子使用了「承諾」的日子,不包括週末。 –

+0

更新了我的答案。 – Uzbekjon

+0

謝謝你!我試圖做一個方法,所以我可以做'@ challenge.dates_challenged',然後我可以遍歷視圖中的日期數組。對困惑感到抱歉。 –

0

簡單和詳細:從您的日期字符串(Date.parse)創建一個日期對象,並創建一個空數組來保存你是「承諾」的日期。如上所述,一週中可用的天數列表存儲在一個數組中。循環直到我們提交存儲在數組中的天數等於請求了多少天,並在前一天添加一天。添加到date_committed數組的日期將根據星期數組的有效天數(days_committed)進行檢查。

require 'date' 

days_challenge = 5 
days_committed = ["mon", "tue", "wed", "thu", "fri"] 
date_started = "2016-04-20" 
date_committed = [] 
date_started_parsed = Date.parse(date_started) 

while (date_committed.size < days_challenge) 
    date_dow = date_started_parsed.strftime('%a').downcase 
    if (days_committed.include?(date_dow)) 
    date_committed << date_started_parsed.strftime('%F') 
    end # if 
    date_started_parsed = date_started_parsed + 1 
end # while 

puts date_committed.to_s 

根據一週的有效天數返回正確的日期。

["2016-04-20", "2016-04-21", "2016-04-22", "2016-04-25", "2016-04-26"]