【问题标题】:Finding the months between two dates in rails在 Rails 中查找两个日期之间的月份
【发布时间】:2018-11-17 11:55:24
【问题描述】:

我目前可以这样设置时间范围:

start_date: "2018-09-11"
end_date: "2018-11-19"

如何在月份开始到结束时执行此操作?示例:

time_range = ["2018-09-11".."2018-09-30"]
time_range = ["2018-10-01".."2018-10-31"]
time_range = ["2018-11-01".."2018-11-19"]

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-4 ruby-on-rails-5


    【解决方案1】:

    我不确定您想要的结果到底是什么,但鉴于开始日期和结束日期为 Date 对象,您可以执行

    (start_date..end_date).to_a.group_by(&:month).values
    

    最后你得到的是一个三元素数组,每个元素都包含一个数组,其中包含一个月内该范围内的所有日期

    【讨论】:

    • 在 Ruby 字符串中(即使是那些表示日期的字符串)没有方法 month。 Rails 中的情况是否有所不同?如果“是”,这不会产生一个其元素(每个对应于一个月)是日期数组的数组吗?如果是这样,您是否没有进一步的步骤将这些日期数组中的每一个转换为一个范围(即使您已获得绿色奖)?
    • @CarySwoveland 我从两个日期对象开始
    • 它是纯红宝石
    • 投票作为最相关的答案
    【解决方案2】:

    我不知道我是否理解你的问题,但我会尽力帮助你。

    Date 类有几个方法可以帮助您处理日期。 Date < Object

    示例

    my_date_range_array = [Date.today.beginning_of_year..Date.today.end_of_year]
    
    my_date_time_range_array = [Time.now.beginning_of_year..Time.now.end_of_year]
    
    my_date_range_array = [6.months.ago..Date.today]
    
    
    YourModel.where date: Date.today.beginning_of_month..Date.today
    
    YourModel.where date: 6.months.ago..Date.today
    

    如果您需要该范围内的每一个日期,您可以使用如下内容:

    (Date.today.beginning_of_year..Date.today.end_of_year).map{ |date| date }
    

    希望我的回答对你有帮助

    【讨论】:

      【解决方案3】:

      这是一个纯 Ruby 解决方案,但我相信(尽管我不了解 Rails)可以通过将我的方法 first_day_of_monthfirst_day_of_month 分别替换为 Rails 方法 beginning_of_monthend_of_month 来稍微简化它.我设计的方法是为了效率而不是简单。

      require 'date'
      
      DATE_FMT = "%Y-%m-%d"
      
      def date_ranges(start_date_str, end_date_str)
        start_date = Date.strptime(start_date_str, DATE_FMT)
        end_date   = Date.strptime(end_date_str, DATE_FMT)
        return [start_date_str..end_date_str] if
          [start_date.year, start_date.month] == [end_date.year, end_date.month]
        d = start_date
        ranges = [start_date_str..last_day_of_month(d)]
        loop do
          d = d >> 1
          break if [d.year, d.month] == [end_date.year, end_date.month]
          ranges << (first_day_of_month(d)..last_day_of_month(d))
        end
        ranges << (first_day_of_month(d)..end_date_str)
      end
      
      def first_day_of_month(d)
        (d - d.day + 1).strftime(DATE_FMT)
      end
      
      def last_day_of_month(d)
        ((d >> 1)-d.day).strftime(DATE_FMT)
      end
      

      date_ranges("2018-09-11", "2019-02-11")
        #=> ["2018-09-11".."2018-09-30", "2018-10-01".."2018-10-31",
        #    "2018-11-01".."2018-11-30", "2018-12-01".."2018-12-31",
        #    "2019-01-01".."2019-01-31", "2019-02-01".."2019-02-11"]
      
      date_ranges("2018-09-08", "2018-09-23")
        #=> ["2018-09-08".."2018-09-23"]
      

      【讨论】:

        【解决方案4】:

        根据 OP 提供的信息,这就是我了解他正在寻找的信息。 例如给定一个范围:

         time_range = "2018-09-11".."2018-09-19"
        
         new_range_min = time_range.min.to_date.beginning_of_month
         new_range_max = time_range.max.to_date.end_of_month
         new_range = new_range_min..new_range_max
        

        【讨论】:

        • 在 Ruby 中你的意思是,不,它没有。接收器本来是一个 Date 对象,感谢您指出问题。正在更新答案。
        猜你喜欢
        • 2012-03-14
        • 2016-02-29
        • 2011-05-01
        • 2019-03-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多