轨道where()和时区



我正在尝试使用以下方法查找今天(在我当前的时区)创建的"条目":

Entry.where("DATE(created_at) = DATE(?) AND email = ?", Time.now, email)

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

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

一旦调用SQL中的DATE()函数,就会丢失对时区信息的跟踪。有两件事需要记住:

  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
)

时间应自动转换为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
)

使用Time.now.utc

使用Time.zone.now。这将使用一个ActiveSupport::TimeWithZone对象,当在数据库搜索中使用时,该对象将自动转换为UTC。

首先,您应该先获取时区,然后再获取时区偏移量。例如current_time_zone是

美国/洛杉矶

时区偏移查找:

 Time.now.in_time_zone(current_time_zone).utc_offset / 3600) * -1

7

控制器中:

 start_date_format = DateTime.strptime(@start_date, date_format)
 start_date_format_with_hour = 
 DateTime.strptime((start_date_format.to_i + timezone_offset*60*60).to_s,'%s').strftime(date_format)
 end_date_format = DateTime.strptime(@end_date, date_format)
 end_date_format_with_hour = DateTime.strptime((end_date_format.to_i + timezone_offset*60*60).to_s,'%s').strftime(date_format)
 @filters_date = "invoices.created_at >= ? AND invoices.created_at < ?", start_date_format_with_hour, end_date_format_with_hour

相关内容

  • 没有找到相关文章

最新更新