Rails/MySQL:不同的用户时区



问题1-我有一个应用程序在德克萨斯州达拉斯共享托管…所以我的数据库/网络服务器当前设置为美国中部时间。。。我无法更改这一点,所以UTC不在讨论范围内。

我的应用程序记录并向用户显示日期和时间数据,但每个用户都可能处于不同的时区。

如果我配置了我的应用程序(config.time_zone = 'Central Time (US & Canada)'),但我允许用户选择他们的时区,

def user_time_zone(&block)
  Time.use_zone(current_user.time_zone, &block)
end

RoR会在用户选择的时区显示任何返回的数据吗?或者,在显示数据之前,我需要评估数据并对其进行相应的修改吗?

问题1.1-我有相关的邮件发送每日/每周/每月报告给用户。如果我使用CRON运行这些,我是否需要将我的工作安排在不同的时间间隔以允许时区?换句话说,如果一个作业包含

when 'daily'
   @dates = params[:f]['Date Range'] = "#{Date.current} - #{Date.current}"

Date.current在东海岸将领先1小时,在西海岸将落后3小时,以此类推。那么(仍然使用Central的服务器时区),我会在晚上11点运行一个(东部),在凌晨2点运行(西部)吗?

非常感谢您的任何建议/协助。谢谢

马特的回答非常清楚。您肯定想将您的时间数据保存在UTC TZ中,然后将其转换为您的用户TZ(或用于访客用户的服务器TZ)

您使用的MySQL全局设置为非UTC TZ,您可以使用以下查询覆盖此设置

SET time_zone = 'UTC';

问题是:这个命令在MySQL中是会话范围的,每次初始化与数据库的新连接时都必须重新设置它。Rails ActiveRecord::ConnectionAdapters::ConnectionPool类可以帮助您实现这一点。请看下面的答案:如何在Rails中对DB连接执行查询?

接下来,你需要在application.rb中设置你的服务器默认TZ(你做到了),并设置每个用户都有自己的TZ(而且你也做到了)

最后,每次访问时间数据时都必须遵守Rails约定。我为您找到了这篇文章,其中充满了非常有用的信息,它将回答您的所有问题:http://www.elabs.se/blog/36-working-with-time-zones-in-ruby-on-rails

摘录自那篇文章:

DO

2.hours.ago # => Fri, 02 Mar 2012 20:04:47 JST +09:00
1.day.from_now # => Fri, 03 Mar 2012 22:04:47 JST +09:00
Date.today.to_time_in_current_zone # => Fri, 02 Mar 2012 22:04:47 JST +09:00
Date.current # => Fri, 02 Mar
Time.zone.parse("2012-03-02 16:05:37") # => Fri, 02 Mar 2012 16:05:37 JST +09:00
Time.zone.now # => Fri, 02 Mar 2012 22:04:47 JST +09:00
Time.current # Same thing but shorter. (Thank you Lukas Sarnacki pointing this out.)
Time.zone.today # If you really can't have a Time or DateTime for some reason
Time.zone.now.utc.iso8601 # When supliyng an API (you can actually skip .zone here, but I find it better to always use it, than miss it when it's needed)
Time.strptime(time_string, '%Y-%m-%dT%H:%M:%S%z').in_time_zone(Time.zone) # If you can't use Time#parse

禁止

Time.now # => Returns system time and ignores your configured time zone.
Time.parse("2012-03-02 16:05:37") # => Will assume time string given is in the system's time zone.
Time.strptime(time_string, '%Y-%m-%dT%H:%M:%S%z') # Same problem as with Time#parse.
Date.today # This could be yesterday or tomorrow depending on the machine's time zone.
Date.today.to_time # => # Still not the configured time zone.

为了获得最佳结果,应用程序的编写应确保其运行所在计算机的时区不会影响任何数据或行为。

这通常意味着在代码中使用UTC。例如,Time.now.utc而不仅仅是Time.now。有关RoR的详细信息,请参阅本文。

最好的做法是尽可能将服务器时区设置为UTC,但这并不意味着您应该在代码中依赖它。

关于你的第二个问题,请记住,每个时区都有自己的"一天"概念。有关可视化信息,请参阅此网站。

您应该在午夜在将数据与之对齐的每个时区运行一个单独的作业。某些应用程序(如StackExchange网站)对所有用户使用一个时区(通常为UTC)。其他应用程序根据每个用户自己的时区调整数据。你需要决定什么适合你的申请。

安排作业时,请确定每个时区午夜对应的UTC时间。然后为该时间安排作业。请确保您的日程安排程序了解这是UTC。不要试图将其调整到服务器的本地时区,否则当本地时区经过夏令时转换时可能会出现错误。

确保计划作业不仅在正确的时间运行,而且报表查询在确定其应运行的UTC范围时使用了正确的时区。

请注意,这确实意味着来自不同时区的两个用户对同一数据进行报告,最终可能会产生不同的结果,因为他们每个"天"的时间段略有不同。

相关内容

  • 没有找到相关文章

最新更新