【问题标题】:Querying for date range in rails在 Rails 中查询日期范围
【发布时间】:2012-09-28 21:31:02
【问题描述】:

我有一个查询今天通话的范围。根据范围,我使用它来计算今天的调用量。

我的日期以 UTC 格式存储,但 rails 会转换为我的本地时区。我要做的是找到今天 00:00 到 23:59 之间的所有电话。

范围:

scope :today, where("DATE(transfer_date) BETWEEN ? AND ?", Time.zone.now.utc.beginning_of_day, Time.zone.now.utc.end_of_day)

irb 输出:(由于 UTC 捕获的调用)

irb(main):010:0> Call.last.transfer_date
  Call Load (0.9ms)  SELECT "calls".* FROM "calls" ORDER BY "calls"."id" DESC LIMIT 1
=> Sun, 07 Oct 2012 19:45:00 CDT -05:00
irb(main):011:0> 

irb(main):011:0> Call.last.transfer_date.utc
  Call Load (1.3ms)  SELECT "calls".* FROM "calls" ORDER BY "calls"."id" DESC LIMIT 1
=> 2012-10-08 00:45:00 UTC

我试图弄清楚如何只查询今天 00:00 到 23:59 之间的电话。到目前为止,尝试使用和不使用 UTC、区域等的范围都行不通。它不断根据 UTC 拉取范围,其中包括昨天的调用(如果它是使用本地时区格式化的,则为昨天)。

如何在两次之间查询以获得正确的输出?我有点迷路了。

【问题讨论】:

  • 能否请你把你的问题说清楚,意思是你给范围的模型,最后你今天没有写成范围。

标签: ruby-on-rails ruby-on-rails-3 activerecord timezone


【解决方案1】:

我能够通过如下重写我的范围来补偿 UTC:

scope :today, where("transfer_date BETWEEN ? AND ?", Time.zone.now.beginning_of_day, Time.zone.now.end_of_day)

【讨论】:

    【解决方案2】:

    您可以使用独占范围。

    scope :today, where(:transfer_date => Date.today...Date.tomorrow)
    

    【讨论】:

      【解决方案3】:

      也许这是矫枉过正,但我​​建议使用辅助方法来获取时间范围,然后查询数据库。类似的东西

      # Gets time range for x number timeunits ago
        def time_range(unit, timeunit = nil)
          if timeunit == "weeks"
            now = Time.zone.now.beginning_of_week
          elsif timeunit == "months"
            now = Time.zone.now.beginning_of_month
          else
            now = Time.zone.now.beginning_of_day
          end
          # Ex: time_range(0, "days") --> Get the time range for today  between the beginning of today and the beginning of tommorow - 1 second
          now - unit.send(timeunit)..now + 1.send(timeunit) - 1.seconds - unit.send(timeunit)
        end
      

      将帮助您请求时间范围。所以当你请求类似的东西时;

      time_range(0, "days")
      

      返回0天前(今天)的时间范围;

      Wed, 07 Sep 2016 00:00:00 UTC +00:00..Wed, 07 Sep 2016 23:59:59 UTC +00:00
      

      然后您可以简单地查询数据库对象并计算范围内的所有内容;

      Calls.where(transfer_date: time_range(unit, timeunit)).count
      

      【讨论】:

      • 这很好,感谢您提供的示例,但几年前我最终使用了一个简单的 lambda 范围 :)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-19
      • 2019-08-16
      • 2014-12-17
      相关资源
      最近更新 更多