从ruby中的日期对象获取日期范围

时间:2014-01-15 14:34:19

标签: ruby-on-rails ruby date

所以我有一个方法可以传递两个日期对象(project_start_date和project_end_date)。我的目标是获取这些对象之间的范围,以便我可以将所有这些日期添加到数组中,然后如果他们选中像每周重复一样的框,那么我可以每周添加一个新的里程碑,直到project_end_date。

现在,作为测试,这作为Ruby脚本运行良好,但现在似乎不能用作rails中的方法(免责声明,我没有编写原始脚本)。具体来说,该函数正在崩溃函数的范围部分((project_start_date..project_end_date).each)。我不认为这是实际日期对象的问题,尽管我认为rails如何将日期存储在子元素中是很奇怪的。

如果它有用,我将日期对象传递给方法的方法是存储end_date,然后使用存储的变量调用方法。

致电方法。

p_start_date = params[:new_basecamp_project][:start_date]
p_start_date.to_s
p_end_date = params[:new_basecamp_project][:end_date]
p_end_date.to_s

完整的功能。

    date_array = []
(project_start_date..project_end_date).each do |date| 

    if (date.strftime("%A") != "Sunday") && (date.strftime("%A") != "Saturday")
        date_array << date
    end

end

weeks = {}
week_num = 1    
single_week_array = []
date_array.each do |date|

    if date.strftime("%A") != "Friday" && (date.to_s) != (date_array.last).to_s
        single_week_array << date
    elsif date.strftime("%A") == "Friday" || (date.to_s) == (date_array.last).to_s
        single_week_array << date
        weeks.merge!(week_num => single_week_array)
        week_num += 1
        single_week_array = []
    end

end
milestones.each do |milestone|

    if milestone.has_key?("duration")
        week_number = milestone["week_number"]
        day_number = milestone["day_number"]
        duration = milestone["duration"]
        start_date = weeks[week_number][(day_number - 1)]
        end_date = date_array[date_array.index(start_date) + (duration - 1)]

        if start_date == nil
            puts "Week or Day number out of range project dates! Milestone start date set to project end date"
            start_date = end_date
        end

        if end_date == nil
            puts "Duration out of range of project dates! Milestone end date set to project end date"
            end_date = project_end_date
        end
        Basecamp::CalendarEntry.new(:project_id => project_hash.id, "title" => milestone["description"], "start-at" => start_date, :deadline => end_date, :type => "CalendarEntry").save                
    else
        (project_start_date..project_end_date).each do |date|

            if date.strftime("%A") == milestone["repeat_weekly"]
                Basecamp::CalendarEntry.new(:project_id => project_hash.id, "title" => milestone["description"], "start-at" => date, :deadline => date, :type => "CalendarEntry").save
            end
        end
    end
end

2 个答案:

答案 0 :(得分:1)

这是一个简单的例子。

@year         = Time.now.utc.year
@start        = Date.parse("#{@year}-1-1")
@finish       = Date.parse("#{@year}-12-31")
@span         = 0..(@finish - @start).to_i
@span.each do |i|
  p i
end

这只是日期数字,但可以很容易地满足您的需求。

答案 1 :(得分:0)

你这样做:

p_end_date = params[:new_basecamp_project][:end_date]
p_end_date.to_s

这不会将p_end_date转换为字符串对象。如果你重新分配它,它会。

p_end_date = p_end_date.to_s

同样p_end_date = params[:new_basecamp_project][:end_date]不会创建DateTime对象,当您对数据库执行保存时,它将在保存时创建这些DateTime对象。如果要在保存之前以这种方式操作它们,则必须手动执行此操作。根据您在表单中获取日期的方式(日期选择器,日期哈希等),您需要创建DateTime对象。您可以在此处查看一些示例:Where is the Rails method that converts data from `datetime_select` into a DateTime object?

所以最简单的方法是将记录保存在数据库中,然后你可以从DB中选择记录,如:

record = SomeModel.last

然后使用这两种方法创建范围:

(record.project_start_date..project_end_date).each do |date|