Jak zmienić domyślną strefę czasową dla Active Record w Railsach?

140

W moim application.rbnatrafiłem na następujący komentarz

# 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)'

Jak widać z góry, dotarłem config.time_zonedo czasu EST. Jednak nadal, gdy rekordy są tworzone w DB, wygląda na to, że datetimesą przechowywane w formacie UTC.

W powyższym komentarzu mówią

... i wykonaj automatyczną konwersję modułu Active Record do tej strefy ...

Jak mogę to zrobić i gdzie?

Wdrożę to również na heroku i chciałbym, aby to ustawienie zostało przeniesione

Wszechobecny
źródło
W MySQL datetime jest typem bez strefy czasowej. To znaczy może być w dowolnej strefie czasowej. Jeśli potraktujesz to jako UTC, to w porządku. Uważaj jednak, jeśli ktoś bezpośrednio zagląda do Twojej bazy danych i inaczej ją interpretuje.
Vanuan

Odpowiedzi:

199

Zdecydowałem się skompilować tę odpowiedź, ponieważ wszystkie inne wydają się niekompletne.

config.active_record.default_timezone określa, czy używać Time.local (jeśli jest ustawiony na: local) lub Time.utc (jeśli jest ustawiony na: utc) podczas pobierania dat i godzin z bazy danych. Wartość domyślna to: utc. http://guides.rubyonrails.org/configuring.html


Jeśli chcesz zmienić strefę czasową Railsów , ale nadal chcesz zapisywać Active Record w bazie danych w UTC , użyj

# application.rb
config.time_zone = 'Eastern Time (US & Canada)'

Jeśli chcesz zmienić strefę czasową Rails ORAZ mieć czas przechowywania Active Record w tej strefie czasowej, użyj

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

Ostrzeżenie : naprawdę powinieneś pomyśleć dwa razy, a nawet trzykrotnie, zanim zapiszesz czasy w bazie danych w formacie innym niż UTC.

Notatka
Nie zapomnij zrestartować serwera Rails po modyfikacji application.rb.


Pamiętaj, że config.active_record.default_timezonemogą przyjmować tylko dwie wartości

  • : lokalna (konwertuje na strefę czasową zdefiniowaną w config.time_zone)
  • : utc (konwertuje na UTC)

Oto, jak możesz znaleźć wszystkie dostępne strefy czasowe

rake time:zones:all
Mihai-Andrei Dinculescu
źródło
5
To wydaje się najbardziej kompletną / dokładną odpowiedzią - @Omnipresent
Aegix
2
To powinna być akceptowana odpowiedź. To jest pełniejsze.
Namiot Enrique Moreno
@ Mihai-AndreiDinculescu Czy uważasz, że lepiej jest przechowywać datetimewartości w UTC w bazie danych, a następnie po prostu zmieniać je w interfejsie użytkownika, jak za pomocą moment.jslub co sugerujesz, aby wyświetlać te dane we właściwej strefie czasowej dla dowolnego użytkownika?
alexventuraio
@AlexVentura Tak, ludzie mądrzejsi ode mnie już dawno zgodzili się, że przechowywanie dat w UTC to najlepszy sposób.
Mihai-Andrei Dinculescu
Tak, mam to. Ale co sugerujesz zaimplementować w widokach railsów, aby pokazać prawidłowe wartości dla każdego użytkownika z inną strefą czasową?
alexventuraio
187

dodawanie kolejnych application.rbprac

 config.time_zone = 'Eastern Time (US & Canada)'
 config.active_record.default_timezone = :local # Or :utc
Wszechobecny
źródło
59
To działa dla mnie z tym:config.time_zone = 'London' config.active_record.default_timezone = :local
Dean Perry
41
Możesz zobaczyć wszystkie strefy czasowe, uruchamiając to w rails c-ActiveSupport::TimeZone.all.map(&:name)
Dean Perry
5
Dzięki wielkie! Ja też się z tym zmagałem. Mam odziedziczoną starszą aplikację PHP, która współdziała z tą samą bazą danych mysql i przechowuje przez cały czas jako lokalną; aktualizacja go do korzystania z UTC nie wchodziła w grę. To, czego wcześniej nie osiągnąłem, nic config.time_zone = 'Central Time (US & Canada)' config.active_record.default_timezone = 'Central Time (US & Canada)' nie dało : ale ustawienie go na: lokalny symbol załatwiło sprawę.
Matt Hucke
8
Prowadnice szyn mówią, że config.active_record.default_timezonepowinno być ustawione tylko na :locallub :utc. Zakładam, że cokolwiek innego przyniosłoby nieoczekiwane rezultaty.
Kelvin
2
Możesz zobaczyć wszystkie strefy czasowe, uruchamiając to wrake time:zones:all
Orlando,
34

Po wielu udrękach doszedłem do tego samego wniosku, co Dean Perry. config.time_zone = 'Adelaide'i config.active_record.default_timezone = :localbyła zwycięską kombinacją. Oto, co znalazłem podczas tego procesu.

James Barona
źródło
5
To jest prawidłowa odpowiedź, default_timezone akceptuje tylko: local lub: utc
Francesco Belladonna
20

W moim przypadku (Rails 5) dodałem te 2 linie do pliku app/config/environments/development.rb

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

Otóż ​​to! Aby upewnić się, że Melbourne zostało poprawnie odczytane, uruchomiłem polecenie w moim terminalu:

bundle exec rake time:zones:all

a Melbourne znajdowało się w strefie czasowej, w której się znajduję!

Carole
źródło
A jeśli chcę, aby każdy użytkownik widział wartości daty i godziny w swojej strefie czasowej?
alexventuraio
@AlexVentura, gdy pokazujesz użytkownikom wartości daty i czasu, przekonwertuj je na ich strefy czasowe. Utrwalanie rekordów bazy danych jest lepszą praktyką
Waheed
10

Jeśli chcesz ustawić globalną strefę czasową na UTC, możesz wykonać następujące czynności w Rails 4:

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

Pamiętaj, aby ponownie uruchomić aplikację, w przeciwnym razie nie zobaczysz zmian.

sergserg
źródło
3

Na torach 4.2.2 przejdź do application.rbi użyj config.time_zone='city'(np. „Londyn”, „Bukareszt” lub „Amsterdam” itd.).

Powinno działać dobrze. U mnie zadziałało.

Andrei Laslo
źródło
3

Musiałem dodać ten blok do mojego environment.rbpliku i wszystko było dobrze :)

Rails.application.configure do
    config.time_zone = "Pacific Time (US & Canada)"
    config.active_record.default_timezone = :local
end
  • Dodałem to przed wierszemRails.application.initialize!
Taylor A. Leach
źródło
1

dla chińskiego użytkownika wystarczy dodać dwie linie poniżej config/application.rb:

config.active_record.default_timezone = :local
config.time_zone = 'Beijing'
Siwei Shen 申思维
źródło
0

W Ruby on Rails 6.0.1 idź do config > locales > application.rb y agrega lo siguiente:

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

Widać, że konfiguruję strefę czasową za pomocą 2 linii:

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

Mam nadzieję, że pomoże to tym, którzy pracują z Ruby on Rails 6.0.1

Juan Castro Lurita
źródło
-2

Jeśli chcesz ustawić czas lokalny, dodaj następujący tekst w 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

Następnie zrestartuj serwer

Anand
źródło
12
default_timezone akceptuje jedną z dwóch opcji ..: local lub: utc .. nie akceptuje określonej strefy czasowej, więc to nie zadziała .. należy ustawić default_timezone na: local
Urkle