处理rails + postgres和timezones

时间:2013-10-03 16:02:44

标签: ruby-on-rails postgresql timezone ruby-on-rails-4 postgresql-9.2

我有一个使用许多不同时区的应用程序......它将它们设置在控制器中,它们会根据用户而改变。所有时间都以UTC格式存储,没有时间戳等。

我的理解是这是Rails处理时区的正常方式。这种方法在99%的时间内工作正常,直到我需要直接使用Postgres做一些事情然后时区成为一个问题。

例如,除了GMT之外,这个查询是完全错误的,例如在中央时区,根据小时设置,它会得到错误的一天:

Events.where("EXTRACT(dow FROM start_at)", Date.today.wday)

我想找到某一天的所有日期。

我正在尝试做这样的事情。我不需要在时区之间进行搜索(它们不会混合),但如果不是UTC则需要指定时区以获得正确的结果。

User.events.where("EXTRACT(dow FROM start_at AT TIME ZONE ?) = ?", 'UTC', Date.today.wday)

但我不确定如何使用Time.zone给我一些可以在Postgres中使用TIME ZONE的东西。

Time.zone.tzinfo有时会有效... Postgres将与'Europe / Warsaw'合作,但Rails将返回'Europe - Warsaw'

总的来说,我对时区没什么好运,任何指针都会受到赞赏。

3 个答案:

答案 0 :(得分:4)

也许其他人有更好的整体解决方案,但您对特定查询的需求是

Time.zone.tzinfo.identifier

或者,在您的示例中:

User.events.where("EXTRACT(dow FROM start_at AT TIME ZONE ?) = ?", Time.zone.tzinfo.identifier, Date.today.wday)

答案 1 :(得分:1)

直接尝试使用Ruby TZInfo gem,而不是使用Rails ActiveSupport::TimeZone

或者,使用MAPPING常量,如ActiveSupport::TimeZone文档中所示,这将使您从Rails时区密钥返回到Postgres和其他人使用的标准IANA时区标识符。 / p>

答案 2 :(得分:0)

Matt Johnson建议直接使用TZInfo gem。这样,您就可以获得使用PostgreSQL查询所需的格式正确的时区标识符。

例如,如果您使用:

TZInfo::Timezone.all_country_zone_identifiers

这将返回一组正确的IANA / Olson时区标识符。换句话说,你将得到正确的“欧洲/华沙”而不是“欧洲 - 华沙​​”。