【问题标题】:MySQL, Rails ActiveRecord date grouping and timezonesMySQL、Rails ActiveRecord 日期分组和时区
【发布时间】:2014-08-08 03:20:05
【问题描述】:

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

 > 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,而我的时区是“巴西利亚”。 我的application.rb 中有这个:

config.time_zone = 'Brasilia'
config.active_record.default_timezone = :local

如何解决?

【问题讨论】:

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


【解决方案1】:

先试试 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 身份运行时区查询。 Here you can find 说明如何安装 trove 并使用 rackspace API 启用 root 访问权限。

【讨论】:

  • 这将是一个完美的答案,但我在 Rackspace 中运行的 MySQL 没有加载时区表。有什么办法可以解决吗?
【解决方案2】:

没有时区功能,只加小时。

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

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

【讨论】:

  • 这是一个很好的技巧,但我还必须考虑夏季节省时间以获得正确的时间。
  • 您可以将 Time.zone 设置为您的时区的当前字符串,然后执行 Time.zone.now.utc_offset / 3600 以确定要使用的确切时间间隔。
【解决方案3】:

即使您的应用程序配置为使用巴西利亚当地时间,您的数据库也始终以 UTC 格式保存(除非您对其进行修改)。当你使用 'where' 语句时,Rails 让你可以选择说出你所在的时区。但是群声明中没有这样的东西。一种解决方案是使用数据库特定功能(如@JaugarChang answer)。另一个正在这样做:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-08-03
    • 1970-01-01
    • 2011-06-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-07
    • 2011-01-23
    • 2018-03-20
    相关资源
    最近更新 更多