我正在尝试显示特定用户时区过去 30 天内每天的展示次数。问题在于,根据时区的不同,计数并不总是相同,我无法在查询中反射(reflect)这一点。
例如,在第一天的 CDT (-5) 晚上 11:00 发生两次展示,在 CDT 凌晨 1:00 发生一次展示。如果您使用 UTC (+0) 进行查询,您将获得在第二天发生的所有 3 次展示,而不是第一天两次和第二天一次。两个 CDT 时间都在 UTC 的第二天。
这就是我现在正在做的,我知道我一定遗漏了一些简单的东西:
start = 30.days.ago
finish = Time.now
# if the users time zone offset is less than 0 we need to make sure
# that we make it all the way to the newest data
if Time.now.in_time_zone(current_user.timezone) < 0
start += 1.day
finish += 1.day
end
(start.to_date...finish.to_date).map do |date|
# get the start of the day in the user's timezone in utc so we can properly
# query the database
day = date.to_time.in_time_zone(current_user.timezone).beginning_of_day.utc
[ (day.to_i * 1000), Impression.total_on(day) ]
end
印象模型:
class Impression < ActiveRecord::Base
def self.total_on(day)
count(conditions: [ "created_at >= ? AND created_at < ?", day, day + 24.hours ])
end
end
我一直在看其他帖子,似乎我可以让数据库为我处理很多繁重的工作,但我没有成功使用像 AT TIME ZONE
这样的东西或 INTERVAL
。
我没有的东西看起来真的很脏,我知道我一定遗漏了一些明显的东西。感谢您的帮助。
最佳答案
好的,在 this awesome article 的帮助下我想我已经想通了。我的问题源于不知道系统 Ruby 时间方法和时区感知 Rails 方法之间的区别。一旦我使用 around_filter like this 为用户设置了正确的时区我能够使用内置的 Rails 方法来大大简化代码:
# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
around_filter :set_time_zone
def set_time_zone
if logged_in?
Time.use_zone(current_user.time_zone) { yield }
else
yield
end
end
end
# app/controllers/charts_controller.rb
start = 30.days.ago
finish = Time.current
(start.to_date...finish.to_date).map do |date|
# Rails method that uses Time.zone set in application_controller.rb
# It's then converted to the proper time in utc
time = date.beginning_of_day.utc
[ (time.to_i * 1000), Impression.total_on(time) ]
end
# app/models/impression.rb
class Impression < ActiveRecord::Base
def self.total_on(time)
# time.tomorrow returns the time 24 hours after the instance time. so it stays UTC
count(conditions: [ "created_at >= ? AND created_at < ?", time, time.tomorrow ])
end
end
我可能还可以做更多的事情,但我现在对此感觉好多了。
关于ruby-on-rails - Rails/Postgres 查询行按时区分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17220905/