如何将整数转换为日期数组?

时间:2016-04-20 21:40:12

标签: ruby-on-rails arrays ruby methods

如果用户使用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,然后我可以遍历日期数组。

4 个答案:

答案 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"]