【问题标题】:Getting range of dates from a date object in ruby从 ruby​​ 中的日期对象获取日期范围
【发布时间】:2014-01-15 14:34:19
【问题描述】:

所以我有一个方法可以传入两个日期对象(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

【问题讨论】:

  • 错误信息是什么?
  • 你试过 (start_date..end_date).to_s 吗?

标签: ruby-on-rails ruby date


【解决方案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

这只是天数,但它可以很容易地满足您的需求。

【讨论】:

    【解决方案2】:

    你正在这样做:

    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?

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

    record = SomeModel.last
    

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

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

    【讨论】:

    • 我其实并不想将它保存到数据库中。一旦逻辑完成,就不需要存储信息,这就是为什么我不将它保存到数据库中。感谢您的快速评论。我不敢相信我错过了“p_end_date = p_end_date.to_s”语法。解决了整个事情。菜鸟失误。感谢您的回答!
    猜你喜欢
    • 1970-01-01
    • 2021-10-25
    • 1970-01-01
    • 2022-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-05
    • 2022-12-18
    相关资源
    最近更新 更多