【问题标题】:ActiveRecord scope to find records created today?ActiveRecord 范围查找今天创建的记录?
【发布时间】:2024-01-07 06:13:01
【问题描述】:

这一定是一件容易的事,但我认为 Rail 的时区实现让我的工作丢了……

如何在 Rails 3(和 ruby​​ 1.9.2)中创建一个范围来查询今天创建的记录?

目前,我正在这样做:

  scope :today, lambda { 
    where("created_at >= ? and created_at <= ?", 
           Date.today.beginning_of_day, Date.today.end_of_day)
  }  

而且它似乎没有按应有的方式工作。我希望“今天”代表用户本地时区从上午 12 点到晚上 11:59 的 24 小时时段。我需要将日期转换为 UTC 吗?

【问题讨论】:

    标签: mysql ruby-on-rails datetime activerecord


    【解决方案1】:

    您需要考虑用户的时区。也就是说,用户时区的一天的开始和一天的结束。为此,首先解析用户时区的当前时间。您可以将区域设置为用户的时区并进行计算,也可以使用以下代码的变体直接解析时间。

    timezone = current_user.timezone # Mountain Time (US & Canada)
    users_current_time = ActiveSupport::TimeZone[timezone].parse(Time.now.to_s)
    

    users_current_time.beginning_of_dayusers_current_time.end_of_day 应该生成正确的时间范围(如果 UTC 是您的应用程序时区,您的应用程序会将其转换为 UTC 并触发查询)

    如果您只想使用范围来执行此操作,那么我建议您设置所有操作的Time.zone = current_user.timezone before_filter 并在范围内使用它。 This railscast 给出了关于如何去做的公平想法。

    【讨论】:

      【解决方案2】:

      如果你用的是mysql,那我想你只想匹配当天,而不是时间对吧?换句话说,您想要从 12 月 1 日开始的所有记录。如果您只搜索日期,则暗示在 12 月 1 日上午 12:00 到晚上 11:59 之间。

       scope :today, lambda { 
          where("created_at = ?",
                 Time.now.strftime("%Y-%d-%m")
        } 
      

      类似的东西应该可以工作

      【讨论】:

      • 只是想知道——对于整个 DateTime 格式是否会返回 true?如果是这样,我多年来一直在用冗长的解决方案解决这个问题。
      • 它将返回一个 SQL 查询,如:“... WHERE created_at = '2010-12-01' ...” MySQL 然后在 12 月 1 日解析为匹配任何内容
      • strtime格式错误,应该是YEAR-MONTH-DAY,如"%Y-%m-%d"
      【解决方案3】:

      这个怎么样?

        scope :today, lambda { 
          where("created_at >= ? and created_at <= ?", 
                 Date.today.beginning_of_day.utc, Date.today.end_of_day.utc)
        }  
      

      【讨论】: