0

我正在开发一个 rail4 应用程序。我想在UTC的所有mysql表中存储日期。但是,我将用户的时区存储在名为users. 当用户登录时,我得到用户的时区user表格并保存在会话中。

我可以在 UTC 的所有表中保存日期,config.time_zone因为 activerecords 和 activemodels 的默认值是 UTC。但是在显示时我想在用户的时区显示日期。此外,当任何用户以任何 html 形式输入日期/时间时,我想将其保存为等效的 UTC 格式。

实现这一目标的最佳方法是什么?

4

2 回答 2

1

您可以将时间存储为 UTC,并单独存储时区。时区通常以秒为单位存储为 UTC 偏移量(秒是 SI 时间单位)。

然后你可以像这样显示它:

utime = Time.now.utc.to_i  # this value can be any format that Time.at can understand. In this example I'll use a unix timestamp in UTC. Chances are any time format you store in your DB will work.
 => 1375944780 

time = Time.at(utime)  # parses the time value (by default, the local timezone is set, e.g. UTC+08:00)
 => 2013-08-08 14:53:00 +0800 
time_in_brisbane = time.in_time_zone(ActiveSupport::TimeZone[36000])  # sets the timezone, in this case to UTC+10:00 (see http://stackoverflow.com/a/942865/72176)
 => Thu, 08 Aug 2013 16:53:00 EST +10:00 
time_brisbane.strftime("%d %b %Y, %l:%M %p %z")  # format with strftime however you like!
 => "08 Aug 2013,  4:53 PM +1000" 
于 2013-08-08T06:57:45.257 回答
1

Rails、activerecord 和 MySQL 将以 UTC 格式保存所有时间戳字段。无需您做任何事情。

application.rb完成应用程序配置的文件中,如果您希望在不同于 UTC 的时区显示时间戳,则定义默认时区。

因此

config.time_zone = 'Central Time (US & Canada)'

将使用中央时间显示时间戳字段(无需您在其他代码中执行任何特殊操作)。

当您希望每个用户的时间戳显示在不同的时区时,您可以将时区存储在用户数据旁边的列中。该列可以被调用time_zone,并且可以包含用户首选时区的字符串。

但是,您必须告诉时间戳对象将自身显示到特定时区。in_time_zone(timezone)这是在DateTime 对象响应的方法的帮助下完成的。

示例(默认时区为 UTC 时):

1.9.3-p194 :004 > d = DateTime.new(2012, 9, 1, 6, 30, 0)
 => Sat, 01 Sep 2012 06:30:00 +0000 
1.9.3-p194 :005 > d.in_time_zone("Central Time (US & Canada)")
 => Sat, 01 Sep 2012 01:30:00 CDT -05:00 

或者,您可以在 before 或 around 过滤器上全局更改手头请求的时区。如果您对此进行谷歌搜索,则互联网上有一个文档。

另请阅读以下内容:http ://api.rubyonrails.org/classes/ActiveSupport/TimeWithZone.html ,了解解决问题的各种替代方法。

于 2013-08-08T08:20:48.457 回答