Rails where()和timezones

Mat*_*ham 2 timezone activerecord ruby-on-rails rails-activerecord

我试图使用以下内容找到今天(在我当前时区)创建的"条目":

Entry.where("DATE(created_at) = DATE(?) AND email = ?", Time.now, email)
Run Code Online (Sandbox Code Playgroud)

Time.now 给我时间在当前区域,但查询似乎是在搜索每个条目的created_at列的UTC时间.

有什么想法我今天能在服务器的时区找到创建的条目吗?

mu *_*ort 14

只要DATE()在SQL中调用函数,就会丢失时区信息.要记住两件事:

  1. 数据库中的所有内容都是 UTC格式,其中包括结果DATE().
  2. 单一的日期(即天)在您的本地时区,可以很容易地横在UTC两个日期,所以你需要看整个时间戳(在这两个侧),而不仅仅是(UTC)日期组件.

这样的事情应该有效:

now = Time.now
Entry.where('created_at between :start and :end and email = :email',
    :start => now.beginning_of_day,
    :end   => now.end_of_day,
    :email => email
)
Run Code Online (Sandbox Code Playgroud)

时间应自动转换为UTC.您可能希望以不同的方式处理上限; 使用end_of_day会让你23:59:59有一个小空间可以让你想要捕获的东西.您可以使用显式的半开间隔(而不是SQL between使用的闭合间隔)来解决该问题,如下所示:

now = Time.now
Entry.where('created_at >= :start and created_at < :end and email = :email',
    :start => now.beginning_of_day,
    :end   => now.tomorrow.beginning_of_day,
    :email => email
)
Run Code Online (Sandbox Code Playgroud)