我有这个范围可以获得滚动的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
答案 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
更常见(或者在时区问题上找到另一种方法),所以在考虑这个最终解决方案之前,你的作业。