1

问题 1 - 我在德克萨斯州达拉斯的共享主机上有一个应用程序...所以我的数据库/Web 服务器当前设置为美国中部时间...我无法更改此设置,因此 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 小时,依此类推。那么(仍然使用中部的服务器时区),我会在晚上 11 点(东部)和凌晨 2 点(西部)运行一个吗?

非常感谢任何和所有建议/帮助。谢谢!

4

2 回答 2

2

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

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

SET time_zone = 'UTC';

问题是:此命令在 MySQL 中是会话范围的,每次初始化与数据库的新连接时都必须重新设置它。Rails ActiveRecord::ConnectionAdapters::ConnectionPool 类可以帮助你。请参阅此答案:如何在 Rails 中对数据库连接执行查询?

接下来,您需要在 application.rb 中设置您的服务器默认 TZ(您这样做了)并设置每个用户拥有自己的 TZ(您也这样做了)

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

从那篇文章中摘录:

做事

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.
于 2013-07-25T15:58:22.693 回答
1

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

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

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

关于第二个问题,请记住,每个时区都有自己的“日”概念。请参阅此站点以获取可视化。

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

在安排您的作业时,请确定每个时区的午夜所对应的 UTC 时间。然后安排那个时间的工作。确保您的调度程序了解它是 UTC。不要尝试将其调整为服务器的本地时区,否则当本地时区经过夏令时转换时,您可能会引入错误。

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

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

于 2013-07-25T13:49:57.250 回答