6

我对时区和 postgresql 数据库(Rails 3.0.4、PostgreSQL 9.0)有疑问。我正在使用自定义范围,我在其中附加了一些条件,进行连接 etc.pp。

问题是,Rails 不会将时间转换为我当地的时区。这是范围的代码:

  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")
  }

within 方法检查范围,Activity.in_week 范围返回:

where("activities.starting_at >= ? AND activities.starting_at < ?", start, stop)

在 select 语句中,我想将starting_at 字段截断为一天。

我得到日期字段的以下输出:

2011-04-07 18:48:32
2011-04-02 14:07:20
2011-04-02 14:06:49

不幸的是,它不包括时区。当我尝试通过“普通”Rails 函数访问我的模型时,它可以工作:

puts Activity.first.starting_at
-> 2011-04-15 06:47:55 +0200

我做错了什么?希望有人能帮忙!

谢谢,晚礼服

4

1 回答 1

5

您的数据库将您的时间戳存储在 UTC 中(应该如此)。当 ActiveRecord 知道它有时间戳时,它正在调整时区;所以,当你这样说时:

puts Activity.first.starting_at

AR 知道这starting_at是一个时间戳,因此它将时间戳实例化为一个ActiveSupport::TimeWithZone实例,并且该类应用时区调整。但是,当你这样说时:

select("date_trunc('day', activities.starting_at) as date ...

AR 不会解析 SQL 以找出date_trunc将返回时间戳,AR 甚至不知道是什么date_trunc意思。AR 只会看到一个字符串从数据库中出来,它会不经解释就把它交给你。您可以自行将该字符串提供给ActiveSupport::TimeWithZone(或您最喜欢的时间处理课程):告诉 AR 自己不知道也无法知道的事情并没有错。

Rails 很聪明,但并不神奇。

于 2011-04-21T08:13:26.050 回答