如果用户使用days_challenge: 5
& committed: ["mon", "tue", "wed", "thu", "fri"]
那么我们如何使用名为date_started: "2016-04-20"
的模型方法创建从dates_challenged
到挑战最后一天的日期数组?
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
,然后我可以遍历日期数组。
答案 0 :(得分: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
答案 1 :(得分: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
答案 2 :(得分: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"]
Previuos回答
假设您处于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"]
答案 3 :(得分:0)
简单和详细:从日期字符串(Date.parse)创建一个日期对象,并创建一个空数组来保存您所提交的日期&#39;提交&#39;至。如上所述,可用的星期几列表存储在一个数组中。循环直到我们提交存储在数组中的天数等于请求了多少天,每隔一天增加一天。添加到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"]