我有一些新闻事件通过postgresql日期时间列存储在数据库中。但是,我想查询事件发生的时间。类似的东西
Event.where("occurred_at < '11:00'")
如果这是一个postgresql时间列,则可以执行此操作。
为了增加一个额外的问题,我将整个应用程序的Rails时区设置为东部时间
config.time_zone = 'Eastern Time (US & Canada)'
因此,如果你试图以某种方式提取数据库时间,该时间将以UTC为单位,因此在半年内,时间比较将延迟1小时(因为夏令时)。
我唯一能想到的就是维护一个单独的"时间"类型的数据库列。
编辑和澄清
这个问题的棘手之处在于,UTC偏移量在半年内会因为夏令时而发生变化。时区解析("2013-01-01 10:00")给出的是2013年1月1日美国东部时间10:00-05:00(即UTC 15:00),而六个月后时区解析(("2013-07-01 10:00")则给出的是美国东部时间2013年7月1日10:00-04:00(即协调世界时14:00)。所以你不能只查询时间而不知道日期。
我已经完全删除并重写了这个答案,因为旧的答案只适用于SQLite,而不适用于OP询问的Postgres。
我能找到的唯一简单的方法(也是最喜欢Rails的方法)就是使用gem。宝石是"tod",可以在这里找到:https://github.com/JackC/tod.
首先,您需要将gem 'tod'
添加到Gemfile并运行捆绑包。然后,您将在DB中创建一个类型为time的列。
将其添加到Event.rb型号中
class Event < ActiveRecord::Base
serialize :time, Tod::TimeOfDay
现在,您有一种方法可以获取时间戳并以序列化格式保存时间(即13:45:00)。TimeOfDay
类将为您提供调用和操作字段所需的方法。
在您的create
操作中,您可以有类似的内容(这假设DB中名为"tod_amp"的列类型为time,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=事件。其中("tod_stamp<?","10:00:00")
您将根据活动记录的实际时间获得结果。如果你所在的时区使用夏令时,那也没关系。您还可以在tod主页上获得TimeOfDay解析、比较和操作的其他方法作为文档。
和往常一样,在我尝试重新发明轮子之前,我应该先找一块宝石。:-)希望这能有所帮助。