将时区范围添加到范围

时间:2015-05-15 20:36:11

标签: ruby-on-rails datetime activerecord

我有这个范围可以获得滚动的14天分析图表的订单。问题是它是否标准UTC,因此如果在PDT时间下午5点之后(UTC和PDT之间的7小时差异)发生销售,销售就会显示为从明天开始。

当前范围:

  scope :recent, complete.joins(:line_items)
    .group("DATE_TRUNC('day', processed_at)")
    .select("DATE_TRUNC('day', processed_at) as day, sum(line_items.discounted_price) as count")
    .order('day DESC').limit(14)

如何才能实现它只能在PDT时区内拉出订单'processed_at'? 不确定如何在语法上做这个,但基本上我想添加'in_time_zone'到'processed_at'时间戳。

调用范围时:

Order Load (2.7ms)  SELECT DATE_TRUNC('day', processed_at) as day, sum(line_items.discounted_price) as count FROM "orders" INNER JOIN "line_items" ON "line_items"."order_id" = "orders"."id" WHERE "orders"."status" = 'complete' GROUP BY DATE_TRUNC('day', processed_at) ORDER BY day DESC LIMIT 14

1 个答案:

答案 0 :(得分:1)

我一直遇到类似的情况。解决方案取决于您正在使用哪种特定操作,但在所有情况下,我优先考虑对查询行为进行狂热的彻底单元测试(使用Timecop或类似方法),以确保它按照我的意愿执行操作正在做。

如果您在WHERE子句中执行此操作,则更容易,因为您可以调整Ruby中的时间戳。这可能看起来像这样:

tz_adjusted_start_time = (Date.today - 14.days - 5.hours)
@result = Thingy.where("processed_at >= ?", tz_adjusted_start_time)

以上产生的SQL将查找在5月2日19:00:00 UTC之后创建的记录,或者其他任何内容。

如果您在不同时区按日期尝试GROUP,那么您需要在原始SQL中进行调整,并且考虑一下它可能会有点毛茸茸,但同样如此原则适用(同样的测试方法也适用)。我以前做过这件事并且很乱,但到目前为止我已经遇到了麻烦。 SQL可能看起来像这样:

...
GROUP BY (`processed_at` - INTERVAL 5 HOUR)
...

我似乎记得使用这种简单的减号语法,但a quick Google search告诉我使用DATE_SUB更常见(或者在时区问题上找到另一种方法),所以在考虑这个最终解决方案之前,你的作业。

祝你好运!