Ruby:将UTC时区更改为UTC或UTC - 区域

时间:2014-07-31 06:40:00

标签: ruby-on-rails ruby datetime

我想将utc时间转换为' utc + 1'或者' utc + something'时区并将其转换回utc时区。

这就是我想做的事情。我要求用户选择UTC时区ex:utc + 4.然后我使用Time.now.utc获取当前UTC时间。现在我想将此时间转换为&ut; + 4'。

在将时间显示到&ut; + 4'之后我想转换回那个时间等效的utc时区。

如何做到这一点?

2 个答案:

答案 0 :(得分:3)

如果您正在使用Ruby On Rails并且您希望更改每个请求的时区并在完成请求后重新设置它。您可以使用Time.use_zone为用户设置时区(文档:http://api.rubyonrails.org/classes/Time.html#method-i-use_zone

以下是我在Rails 4.1中测试的内容。

首先,建议为config.time_zone设置合理的默认值(在config / application.rb中),我设置为“Mumbai”(UTC + 5.30)。 (要列出时区,您可以使用命令bundle exec rake time:zones:all

module MyApp
  class Application < Rails::Application
     config.time_zone = 'Mumbai'
  end
end

在您的项目中,运行rails g model User name:string time_zone:stringbundle exec rake db:migrate

然后,通过rails控制台创建一些测试用户,运行rails c

Loading development environment (Rails 4.1.4)
irb(main):001:0> first_user = User.create!(name: 'zdk', time_zone: 'Bangkok')
   (0.1ms)  begin transaction
  SQL (0.4ms)  INSERT INTO "users" ("created_at", "name", "time_zone", "updated_at") VALUES (?, ?, ?, ?)  [["created_at", "2014-07-31 09:21:13.750710"], ["name", "zdk"], ["time_zone", "Bangkok"], ["updated_at", "2014-07-31 09:21:13.750710"]]
   (0.6ms)  commit transaction
=> #<User id: 1, name: "zdk", time_zone: "Bangkok", created_at: "2014-07-31 09:21:13", updated_at: "2014-07-31 09:21:13">
irb(main):002:0> second_user = User.create!(name: 'joe', time_zone: 'London')
   (0.1ms)  begin transaction
  SQL (0.8ms)  INSERT INTO "users" ("created_at", "name", "time_zone", "updated_at") VALUES (?, ?, ?, ?)  [["created_at", "2014-07-31 09:21:31.299606"], ["name", "joe"], ["time_zone", "London"], ["updated_at", "2014-07-31 09:21:31.299606"]]
   (1.9ms)  commit transaction
=> #<User id: 2, name: "joe", time_zone: "London", created_at: "2014-07-31 09:21:31", updated_at: "2014-07-31 09:21:31">
irb(main):003:0>

尝试查询我们刚刚创建的内容,您可以看到它使用您在Application config(config.time_zone)中设置的时区。 输出:

irb(main):003:0> first_user.created_at
=> Thu, 31 Jul 2014 14:51:13 IST +05:30
irb(main):005:0> second_user.created_at
=> Thu, 31 Jul 2014 14:51:31 IST +05:30

如何使用Time.zone处理每个请求的基准时区。 转到ApplicationController(app / controllers / application_controller.rb文件)。 创建一个方法,设置around_filter调用的时区(更多详细信息:http://www.elabs.se/blog/36-working-with-time-zones-in-ruby-on-rails)。我也创建了hello action,将从root url路由。像这样:

class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
  around_filter :set_time_zone

  def set_time_zone
   if true #if user loggin ?
     @user = User.first #Change to User.last to see the result.
     Time.use_zone(@user.time_zone) { yield }
   else
     yield
   end
  end

  def hello
    render plain: "Hello, user: #{@user.name}. Created: #{@user.created_at}"
  end

end

通过编辑配置路由(config / routes.rb)将应用程序uri路由到您的控制器方法

Rails.application.routes.draw do
  root 'application#hello'
end

如果你正确设置了一切。你应该有这种格式的输出

第一位用户:Hello, user: zdk. Created: <Date> <Time> +0700

第二位用户

Hello, user: joe. Created: <Date> <time> +0100

总之,流程类似于:

               +------------+
               |   APP      |
               +------------+


           +           Use the Time.zone value instead if it's set
           |                      ^
       WRITE                      |
           v                      |  READ
                                  +
 Convert to UTC        Convert from UTC to config.time_zone
           +                      ^
           |                      |
       WRITE                      |  READ
           |                      |
           v                      +
       +--------------------------------+
       |                                |
       |           DB                   |
       |                                |
       |          UTC                   |
       +--------------------------------+

希望这有帮助。

答案 1 :(得分:0)

您可以使用ActiveSupport::TimeWithZone

示例:

#Define a TimeZone
Time.zone = 'Eastern Time (US & Canada)' # => 'Eastern Time (US & Canada)'
#Define a utc time
t = Time.utc(2007, 2, 10, 20, 30, 45)    # => '2007-02-10 20:30:45 UTC
#same time with gmt -5
t.in_time_zone                           # => Sat, 10 Feb 2007 15:30:45 EST -5:00