如何在Rails中更改Active Record的默认时区?

159

在我的application.rb文件中,我遇到了以下评论

# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
 config.time_zone = 'Eastern Time (US & Canada)'

从上面可以看出,我已经将config.time_zone设置为东部标准时间。然而,在数据库中创建记录时,datetime仍然以UTC格式存储。

在上面的评论中,他们说:

  

...并使Active Record自动转换到此区域...

我该如何做到这一点,并在哪里进行设置?

另外,我将在Heroku上部署它,我希望设置能够跨越部署。


在MySQL中,datetime是一种无时区类型。也就是说,它可以处于任何你想要的时区。如果你将其视为UTC,那么没问题。但是要注意,如果有人直接查看并解释数据库中的数据,可能会产生不同的结果。 - Vanuan
10个回答

245

我决定编写这篇答案,因为所有其他答案似乎都不完整。

config.active_record.default_timezone 确定在从数据库中提取日期和时间时是否使用 Time.local(如果设置为 :local)或 Time.utc(如果设置为 :utc)。默认值为 :utc。 http://guides.rubyonrails.org/configuring.html


如果您想更改Rails的时区,但仍希望Active Record保存在UTC中,请使用

# application.rb
config.time_zone = 'Eastern Time (US & Canada)'
如果你想要改变Rails的时区,并且让Active Record以这个时区存储时间,使用以下代码:
```ruby config.time_zone = 'Your Time Zone' config.active_record.default_timezone = :local ```
# application.rb
config.time_zone = 'Eastern Time (US & Canada)'
config.active_record.default_timezone = :local

警告: 在非UTC格式下保存时间到数据库之前,您应该三思而后行。

注意:
修改完application.rb之后,请不要忘记重新启动Rails服务器。


请记住,config.active_record.default_timezone只有两个取值:

  • :local(转换为config.time_zone中定义的时区)
  • :utc(转换为UTC)

以下是找到所有可用时区的方法:

rake time:zones:all

7
这似乎是最完整/准确的答案 --@Omnipresent - Aegix
3
这应该是被接受的答案。它更加完整。 - Enrique Moreno Tent
@AlexVentura 是的,比我聪明的人们早就同意将日期存储在协调世界时是最佳选择。 - Mihai Dinculescu
@AlexVentura,除非你让他们告诉你他们机器的时区,否则你无法做到。用一点JavaScript应该不难。假设这个JavaScript给你秒数+/- UTC(例如3600是+1小时),你可以在控制器“before”过滤器中像这样使用它:Time.zone = Time.find_zone!params.fetch(:utc_offset) - Adamantish
既然需要使用JavaScript,那么使用moment.js可能会更简单。 - Adamantish
显示剩余3条评论

198

将以下内容添加到application.rb中可以生效:

 config.time_zone = 'Eastern Time (US & Canada)'
 config.active_record.default_timezone = :local # Or :utc

61
这对我来说有效:config.time_zone = 'London' config.active_record.default_timezone = :local - user358380
41
你可以在 rails c 中运行以下命令来查看所有的时区:ActiveSupport::TimeZone.all.map(&:name) - user358380
5
非常感谢!我也一直在为此苦苦挣扎。我有一个继承下来的遗留PHP应用程序,它与同一个mysql数据库进行交互,并将所有时间都存储为本地时间;将其更新为使用UTC不是一个选项。之前我所完成的无用功:config.time_zone = 'Central Time (US & Canada)' config.active_record.default_timezone = 'Central Time (US & Canada)'但将其设置为:local符号就解决了问题。 - Matt Hucke
8
Rails指南说,config.active_record.default_timezone只应设置为:local:utc。我认为任何其他设置都会产生意料之外的结果。 - Kelvin
2
您可以通过在rake time:zones:all中运行此命令来查看所有时区。 - Orlando
显示剩余8条评论

34

在经历了许多痛苦之后,我得出了与Dean Perry相同的结论。 config.time_zone = 'Adelaide'config.active_record.default_timezone = :local 是胜利的组合。在这个过程中,这是我发现的


5
这是正确的答案,default_timezone 只接受 :local 或 :utc。 - Francesco Belladonna

24

在我的情况下(Rails 5),我最终在app/config/environments/development.rb中添加了这两行内容。

config.time_zone = "Melbourne"
config.active_record.default_timezone = :local

就这样!为确保正确读取墨尔本时区,我在终端中运行了以下命令:

bundle exec rake time:zones:all

然后墨尔本以我所在的时区列出了!


如果我希望每个用户在自己的时区中查看日期时间值怎么办? - alexventuraio
@AlexVentura 当您向用户显示日期时间值时,请将其转换为他们所在的时区。使数据库记录持久化是更好的实践。 - Waheed

12

如果您想在全局范围内将时区设置为UTC,可以在Rails 4中执行以下操作:

# Inside config/application.rb
config.time_zone = "UTC"
config.active_record.default_timezone = :utc

确保重新启动您的应用程序,否则您将看不到更改。


5
在Ruby on Rails 6.0.1中,前往 config > locales > application.rb 并添加以下内容:
require_relative 'boot'

require 'rails/all'

# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)

module CrudRubyOnRails6
  class Application < Rails::Application
    # Initialize configuration defaults for originally generated Rails version.
    config.load_defaults 6.0

    config.active_record.default_timezone = :local
    config.time_zone = 'Lima'

    # Settings in config/environments/* take precedence over those specified here.
    # Application configuration can go into files in config/initializers
    # -- all .rb files in that directory are automatically loaded after loading
    # the framework and any gems in your application.
  end
end

您可以看到,我使用了两行代码来配置时区。
config.active_record.default_timezone =: local
config.time_zone = 'Lima'

我希望这些内容能够帮助那些正在使用Ruby on Rails 6.0.1的人。

4
我不得不在我的environment.rb文件中添加这个块,然后一切都好了 :)
Rails.application.configure do
    config.time_zone = "Pacific Time (US & Canada)"
    config.active_record.default_timezone = :local
end
  • 我将它添加到了Rails.application.initialize!这行之前

3

在Rails 4.2.2版本中,进入application.rb文件并使用config.time_zone='城市'(例如:'伦敦'、'布加勒斯特'、'阿姆斯特丹'等)即可。

这样做应该可以正常工作。我已经尝试过了。


1

对于中文用户,只需在config/application.rb中添加以下两行:

config.active_record.default_timezone = :local
config.time_zone = 'Beijing'

-2
如果您想设置本地时间,请在application.rb中添加以下文本。
config.time_zone = 'Chennai'

# WARNING: This changes the way times are stored in the database (not recommended)
config.active_record.default_timezone = :local

然后重新启动您的服务器


12
default_timezone 接受两个选项::local 或 :utc。它不接受特定的时区,因此这种设置是无效的。你需要将 default_timezone 设置为 :local。 - Urkle

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接