Rails4:在用户的时区中保存和显示日期

时间:2013-08-06 02:52:01

标签: ruby-on-rails ruby ruby-on-rails-4

我正在开发一个rails4应用程序。我希望在UTC中的所有mysql表中存储日期。但是,我将用户的时区存储在一个名为users的特定表中。当用户登录时,我会获得用户的时区形式user表并保存在会话中。

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

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

2 个答案:

答案 0 :(得分: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" 

答案 1 :(得分:1)

Rails,activerecord和MySQL将以UTC格式保存所有时间戳字段。没有你必须做任何事情。

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

因此

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

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

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

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

示例(默认时区为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 

或者您可以在前置或左右过滤器上全局更改当前请求的时区。如果您在谷歌上有一个关于互联网的文档。

另请阅读本文:http://api.rubyonrails.org/classes/ActiveSupport/TimeWithZone.html 寻求解决问题的各种替代方案。