我有一些通过postgresql datetime列存储在数据库中的新闻事件。但是,我想对事件发生的时间进行查询。像
这样的东西Event.where("occurred_at < '11:00'")
如果这是postgresql时间列,你可以这样做。
要添加额外的皱纹,我将Rails时区设置为整个应用程序的东部时间
config.time_zone = 'Eastern Time (US & Canada)'
因此,如果您尝试以某种方式提取数据库时间,则该时间将采用UTC,因此在半年期间,时间比较将减少1小时(因为夏令时)。
我唯一能想到的是维护一个单独的'time'类型的数据库列。
编辑和澄清
这个问题的棘手部分是由于夏令时,UTC偏移在半年内发生变化。 Time.zone.parse(“2013-01-01 10:00”)给出2013年1月1日10:00 EST -05:00(即15:00 UTC),六个月后Time.zone.parse(“2013- 07-01 10:00“)给出2013年7月1日10:00 EDT -04:00(即UTC时间14:00)。所以你不能在不知道日期的情况下查询时间。
答案 0 :(得分:3)
我已经完全删除并重写了这个答案,因为旧的答案只适用于SQLite,而不是OP询问的Postgres。
我能找到的唯一简单方法(和Rails一样)是使用宝石。宝石是“tod”,可以在这里找到:https://github.com/JackC/tod。
首先,您需要将gem 'tod'
添加到Gemfile并运行bundle。然后,您将在时间类型的数据库中创建一个列。
将此添加到Event.rb模型
class Event < ActiveRecord::Base
serialize :time, Tod::TimeOfDay
现在,您可以通过序列化格式获取时间戳并节省时间(即13:45:00)。 TimeOfDay
类将为您提供调用和操作字段所需的方法。
在您的create
操作中,您可以拥有类似的内容(这假设数据库中的列名为“tod_stamp”,类型为时间,而DateTime对象名为:occured_at ):
def create
@event = Event.new(event_params)
tod_stamp = @event.occured_at.strftime('%H:%M:%S')
@event.tod_stamp = TimeOfDay.parse(tod_stamp)
respond_to do |format|
if @event.save
format.html { redirect_to @event, notice: 'Event was successfully created.' }
format.json { render action: 'show', status: :created, location: @event }
else
format.html { render action: 'new' }
format.json { render json: @event.errors, status: :unprocessable_entity }
end
end
end
现在当你向DB询问类似的内容时:
my_events = Event.where(“tod_stamp&lt;?”,“10:00:00”)
您将根据活动记录的实际时间获得结果。如果您处于使用夏令时的时区,则无关紧要。您还可以在tod主页上获取TimeOfDay解析,比较和操作的其他方法作为文档。
像往常一样,在尝试重新发明轮子之前,我应该寻找宝石。 :-)希望这有帮助。