Querying time of day from in a Rails datetime column (with time zones)
我有一些通过postgresql datetime列存储在数据库中的新闻事件。但是,我想对事件发生的时间进行查询。就像是
1 | Event.where("occurred_at < '11:00'") |
如果这是postgresql时间列,你可以做什么。
为了增加额外的皱纹,我将Rails时区设置为整个应用程序的东部时间
1 | 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)。因此,您不仅可以在不知道日期的情况下查询时间。
我已经完全删除并重写了这个答案,因为旧答案只适用于SQLite而不是OP所询问的Postgres。
我能找到的唯一简单方法(和Rails一样)是使用宝石。宝石是"tod",可以在这里找到:https://github.com/JackC/tod。
首先,您需要将
将其添加到Event.rb模型中
1 2 | class Event < ActiveRecord::Base serialize :time, Tod::TimeOfDay |
现在,您可以通过序列化格式获取时间戳并节省时间(即13:45:00)。
在您的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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 <?","10:00:00")
您将根据活动记录的实际时间获得结果。如果您处于使用夏令时的时区,则无关紧要。您还可以在Tod主页上获取TimeOfDay解析,比较和操作的其他方法作为文档。
像往常一样,在尝试重新发明轮子之前,我应该寻找宝石。 :-) 希望这可以帮助。