如何正确转换或查询Rails/MySQL DateTime列的日期范围

如何正确转换或查询Rails/MySQL DateTime列的日期范围,sql,mysql,ruby-on-rails,ruby,datetime,Sql,Mysql,Ruby On Rails,Ruby,Datetime,我有一个rails应用程序,将创建的_存储为datetime(标准)。 我正在构建一个用于搜索的表单,我发现我必须使用find_by_sql来执行一些复杂的子查询。表单有一个日期范围(无时间)可用于搜索在字段中创建的项目 我发现的问题是,如果我只传入要查询的范围的日期字符串 ... status_changes.created_at between '2009-01-24' and '2009-03-12' ... 我正在返回在2009-01-23 17:10:39-0800日期创建了_的记录

我有一个rails应用程序,将创建的_存储为datetime(标准)。 我正在构建一个用于搜索的表单,我发现我必须使用find_by_sql来执行一些复杂的子查询。表单有一个日期范围(无时间)可用于搜索在字段中创建的项目

我发现的问题是,如果我只传入要查询的范围的日期字符串

... status_changes.created_at between '2009-01-24' and '2009-03-12' ...
我正在返回在2009-01-23 17:10:39-0800日期创建了_的记录,因为它以2009-01-24 01:10:39(UTC)的形式存储在数据库中

如何修复此问题,使结果不会返回有问题的记录

似乎我需要将日期范围转换为UTC特定的,或者告诉find_by_sql根据当前时区进行搜索,而不是将列读取为UTC

有人要吗

John

MySQL有一个函数,可以获取日期时间并将其从一个时区转换为另一个时区。您可以构建查询以将存储值(UTC)转换为本地时区(PST)


如果您不使用
find\u by\u sql
,而是使用
find
和让Rails进行替换的
:conditions
子句,它将自动转换所有内容

Model.find :all, 
  :conditions => ["created_at between ? and ?", start_date, end_date]
最糟糕的情况是,如果Rails被日期搞混了,您可以将它们转换为时间,它应该会玩得很好:

Model.find :all, 
  :conditions => ["created_at between ? and ?", 
                   start_date.to_time, end_date.to_time]

我知道这是一个老问题,但在回答有关CONVERT_TZ的流线型查询时:

除非加载了mySQL命名的时区表(在普通安装中不太可能),否则需要输入时区作为UTC的偏移量

CONVERT_TZ(status_changes.created_at, '+00:00', '+08:00') between '2009-01-24' and '2009-03-12')

我试过伊恩的答案,但不太管用。Rails在保存和加载记录时正确地处理了时区,但对于查询参数似乎没有这样做。请注意,我正在使用的应用程序是Rails 2.1.1中的,因此从那时起情况可能有所改善


通过一个小小的调整,我能够让Ian的解决方案工作:使用getutc方法获取UTC时区中的时间值,然后将其作为参数传递。这也不会对任何可能正确处理时间参数区域的Rails的更高版本造成任何伤害,因为getutc不会更改UTC时间,而只是更改时区。

因为Rails将日期存储在数据库中,所以您应该在
time
DateTime
上使用
UTC
方法

i、 e


执行此操作的现代ActiveRecord方法是:

Model.where(time_field: date1..date2)

为我工作(:from是“date”类型的数据库字段)

谢谢。我不确定我是否能很快测试这个,但你的答案似乎是可信的。
Model.find :all, 
  :conditions => ["created_at between ? and ?", start_date.utc, end_date.utc]
Model.where(time_field: date1..date2)
Model.where(:from => "2012-01-01".to_date.."2012-06-30".to_date)