在PostgreSQL中将时间戳转换为查询中的时区(Rails)

问题描述 投票:1回答:2

经过这个时间的头撞。

我试图通过日期组将查询模型与PG分离为模型start_time(以UTC格式存储)。

  • 早上(12a - 12p)
  • 下午(12p - 5p)
  • 晚上(5p - 12a)

我已经尝试了范围方法,实例方法查询和整体类方法。所有这些都按UTC返回日期组(不是预定事件的本地时区)

# event.rb
def self.morning
  startday = 0
  midday = 12
  Event.where("extract(hour from start_time) >= ? AND extract(hour from start_time) < ?", startday, midday)
end

也尝试过,

def self.afternoon
  midday = "12:00:00"
  eveday = "17:00:00"
  Event.where("start_time::time >= ? AND start_time::time < ?", midday, eveday)
end

当控制台提示时(通常在整个应用程序中)我调用event.start_time在本地时区成功返回(在application.rb文件中设置)

但除非在模型外部调用,否则start_time继续查询为UTC。

我不想预设数据库时区(因为这是不好的做法,全局使用该应用程序)

编辑

作为视图中的一个例子,我正在打电话

<% events.morning.order("start_time ASC").each do |fit_class| %>
...

哪里,

events = @events = Event.all # passed through a partial
ruby-on-rails postgresql
2个回答
0
投票

只需为时区检查添加事件模型的范围

class Event < ApplicationRecord

  scope :morning, -> { where(
    "start_time >= ? AND start_time < ?",
      formatted_time(0), formatted_time(12))
  }

  scope :afternoon, -> { where(
    "start_time >= ? AND start_time < ?",
      formatted_time(12), formatted_time(17))
  }

  scope :evening, -> { where(
    "start_time >= ? AND start_time < ?",
      formatted_time(17), formatted_time(24))
  }

  private

  def formatted_time(hour = 0)
    Time.zone.parse(Date.current.to_s).change(hour: hour)
  end
end

您不必修改此查询的任何其他时区设置。希望能帮助到你!


0
投票

对于旁观者,我的临时解决方案如下(对PostgreSQL文档的研究很多):

def self.morning
  startday = 0
  midday = 12
  Event.where("extract(hour from start_time - interval '6 hours') >= ? AND extract(hour from start_time - interval '6 hours') < ?", startday, midday)
end

def self.afternoon
  midday = 12
  eveday = 17
  Event.where("extract(hour from start_time - interval '6 hours') >= ? AND extract(hour from start_time - interval '6 hours') < ?", midday, eveday)
end

def self.evening
  eveday = 17
  endday = 24
  Event.where("extract(hour from start_time - interval '6 hours') >= ? AND extract(hour from start_time - interval '6 hours') < ?", eveday, endday)
end

这要求我预设应用时区。

# application.rb
config.time_zone = "Central Time (US & Canada)"

发现时我会更改完整解决方案更新!

© www.soinside.com 2019 - 2024. All rights reserved.