我正在开发一个rails4应用程序。我希望在UTC中的所有mysql表中存储日期。但是,我将用户的时区存储在一个名为users
的特定表中。当用户登录时,我会获得用户的时区形式user
表并保存在会话中。
我能够以UTC格式保存所有表格中的日期,因为config.time_zone
的默认值是activerecords和activemodels的UTC。但在显示时我想在用户的时区显示日期。同样,当任何用户以任何html格式输入日期/时间时,我想以等效的UTC格式保存它。
实现这一目标的最佳方法是什么?
答案 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 寻求解决问题的各种替代方案。