Rails不会转换时区(PostgreSQL) [英] Rails doesn't convert timezone (PostgreSQL)
问题描述
我对时区和postgresql数据库(Rails 3.0.4,PostgreSQL 9.0)有问题。我正在使用自定义范围,在其中添加了一些条件,进行了连接等。
I have a problem with timezones and a postgresql db (Rails 3.0.4, PostgreSQL 9.0). I'm using a custom scope, in which I append some conditions, do joins etc.pp.
问题是,Rails不会将时间转换为我的时间当地时区。
以下是范围的代码:
The problem is, that Rails don't convert the times to my local timezone. Here is the code of the scope:
scope :with_activities_within_range_in_week, lambda{ |latMin, lngMin, latMax, lngMax, date|
select("date_trunc('day', activities.starting_at) as date,
count(activities.id) as value
") \
.within(latMin, lngMin, latMax, lngMax) \
.joins(:activities) \
.merge(Activity.in_week(date)) \
.group("date") \
.order("date")
}
内部方法检查范围, Activity.in_week范围返回以下内容:
The within method checks for ranges, the Activity.in_week scope returns this:
where("activities.starting_at >= ? AND activities.starting_at < ?", start, stop)
然后在select语句中,我想今天删节starting_at字段。
And in the select statement, I want to trunc the starting_at field to day.
我在日期字段中得到以下输出:
I'm getting the following output for the date field:
2011-04-07 18:48:32
2011-04-02 14:07:20
2011-04-02 14:06:49
很遗憾,它不包含时区。当我尝试通过正常 Rails函数访问模型时,它会起作用:
Unfortunately it doesn't include the timezone. When I try to access my model through the "normal" Rails functions, it works:
puts Activity.first.starting_at
-> 2011-04-15 06:47:55 +0200
我在做什么错?希望有人能帮忙!
What I'm doing wrong? Hope someone can help!
thx,
晚礼服
thx, tux
推荐答案
您的数据库正在将时间戳存储在UTC中(应如此)。当ActiveRecord知道有时间戳时,它将进行时区调整。因此,当您这样说:
Your database is storing your timestamps in UTC (as it should). ActiveRecord is making timezone adjustments when it knows that it has a timestamp; so, when you say this:
puts Activity.first.starting_at
AR知道 starting_at
是一个时间戳,因此将时间戳实例化为 ActiveSupport :: TimeWithZone
实例,该类将应用时区调整。但是,当您这样说:
AR knows that starting_at
is a timestamp so it instantiates the timestamp as an ActiveSupport::TimeWithZone
instance and that class applies the timezone adjustment. But, when you say this:
select("date_trunc('day', activities.starting_at) as date ...
AR不会解析SQL以找出 date_trunc
将返回一个时间戳,AR甚至都不知道 date_trunc
是什么意思,AR只会从数据库中看到一个字符串,并将其传递给您无需任何解释,就可以自己随意将字符串提供给 ActiveSupport :: TimeWithZone
(或您最喜欢的时间处理类):告诉AR事情没有错
AR isn't going to parse the SQL to figure out that date_trunc
will return a timestamp, AR doesn't even know what date_trunc
means. AR will just see a string coming out of the database and it will hand it to you without interpretation. You are free to feed that string to ActiveSupport::TimeWithZone
(or your favorite time handling class) yourself: there's nothing wrong with telling AR things that it does not and cannot know on its own.
路轨很聪明,但不是魔术。
Rails is clever but it isn't magic.
这篇关于Rails不会转换时区(PostgreSQL)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!