在Active Record order子句中使用mysql函数

时间:2016-04-28 21:32:40

标签: mysql ruby-on-rails ruby timezone

我有一张表sessions,其中包含日期时间字段starts_atstarts_at以UTC格式存储,但我想在本地时间返回按starts_at排序的会话,而不是日期时间。

所以如果我的会话日期时间为:

s1 Jan 1, 13:00
s2 Jan 2, 11:00
s3 Jan 1, 23:00

如果不考虑时区,我希望它们按此顺序返回:s2, s1, s3

现在我希望在当地时间获得所有时间,因为我们可以说时区有效增加了2个小时。 s2, s1, s3的顺序现在是错误的。我们想要s3,s2,s1。

我一直在尝试的是:

Session.order("CONVERT_TZ(starts_at,'UTC', '#{tz}')")

Session.order("TIME(CONVERT_TZ(starts_at,'UTC', '#{tz}'))")

tz = Time.now.strftime('%Z')(在此之前我还将Time.now.zone设置为所有会话将在的时区)

不幸的是,这给了我奇怪的结果,似乎没有任何顺序。

2 个答案:

答案 0 :(得分:1)

取决于你的tz设置为......可能它无效.. 我能够明确指定像这样的小时数

SELECT *,TIME(starts_at),TIME(CONVERT_TZ(TIME(starts_at),'+00:00', '+2:00')) FROM 
sessions
ORDER BY TIME(CONVERT_TZ(TIME(starts_at),'+00:00', '+2:00'))

http://sqlfiddle.com/#!9/1e0ef/8

答案 1 :(得分:1)

因此,您希望按小时和分钟(忽略日期)对这些进行排序,但您希望首先转换为您的本地时区,以便第一个项目在午夜(当地时间)之后。

Session.order("HOUR(CONVERT_TZ(starts_at, 'UTC', '#{tz}')), MINUTE(starts_at)")

您可以在转换为当地时间后提取小时。您可以在不转换的情况下提取分钟部分(除非您有分数时区)。