MySQL,Rails ActiveRecord日期分组和时区

时间:2014-08-08 03:20:06

标签: mysql ruby-on-rails ruby activerecord timezone

我想按创建日期计算用户数。 当我查询我的上一个用户时,我有:

 > User.last.created_at
 => Thu, 07 Aug 2014 21:37:55 BRT -03:00

当我计算每个日期的用户时,我得到了这个:

> User.group("date(created_at)").count
=>  {Fri, 08 Aug 2014=>1}

创建日期是8月7日,但结果是8月8日。这是因为组条件是UTC,我的时区是'Brasilia'。 我在application.rb

中有这个
config.time_zone = 'Brasilia'
config.active_record.default_timezone = :local

如何解决这个问题?

3 个答案:

答案 0 :(得分:4)

首先尝试convert_tz:

User.group("date(convert_tz(created_at,'UTC','[your_time_zone]'))").count

如果convert_tz返回null,则可能需要使用以下命令行加载时区表:

$ mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root mysql

参考mysql convert_tz

编辑1:

如果您使用Rackspace MySQL,则需要启用对数据库的root访问权限并以root身份运行时区查询。关于如何使用rackspace API安装trove并启用root访问权限的Here you can find说明。

答案 1 :(得分:1)

没有时区功能,只需加上几小时。

User.group("date(created_at + INTERVAL 8 HOUR)").count

加上8小时是上海的时区。欢迎来到上海。

答案 2 :(得分:0)

即使您的应用程序配置为使用Brasilia Local Time,您的数据库也始终以UTC格式保存(除非您修改它)。当您使用'where'语句时,Rails会让您选择说出您所在的时区。但群体声明没有这样的事情。一种解决方案是使用数据库特定的功能(如@JaugarChang回答)。另一个是这样做:

group = User.group("date(created_at)").count
results = group.map{|date, count| {Time.zone.utc_to_local(DateTime.parse(date)).to_date => count } }
  • Pro:您不依赖于特定的数据库本机功能 转换时区;
  • Con:与第一个相比没那么快。 需要更多的时区知识才能让程序员理解 这是怎么回事。