Come modificare il fuso orario predefinito per Active Record in Rails?


140

Nel mio application.rbmi sono imbattuto nel seguente commento

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

Come vedi dall'alto, ho fatto config.time_zonel'ora EST. Tuttavia, anche quando i record vengono creati nel DB, sembra che datetimevengano memorizzati nel formato UTC.

Nel commento sopra, dicono

... e converti automaticamente Active Record in questa zona ...

Come posso farlo e dove?

Inoltre, lo distribuirò anche su Heroku e mi piacerebbe che l'impostazione continuasse


In MySQL datetime è un tipo senza fuso orario. Cioè potrebbe essere in qualsiasi fuso orario che desideri. Se lo tratti come UTC va bene. Ma fai attenzione se qualcuno sta guardando direttamente nel tuo database e lo interpreta in modo diverso.
Vanuan,

Risposte:


199

Ho deciso di compilare questa risposta perché tutti gli altri sembrano essere incompleti.

config.active_record.default_timezone determina se utilizzare Time.local (se impostato su: local) o Time.utc (se impostato su: utc) quando si estraggono date e orari dal database. L'impostazione predefinita è: utc. http://guides.rubyonrails.org/configuring.html


Se si desidera modificare il fuso orario di Rails , ma continuare a salvare Active Record nel database in UTC , utilizzare

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

Se si desidera modificare il fuso orario di Rails E avere orari di archiviazione dei record attivi in questo fuso orario, utilizzare

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

Attenzione : dovresti davvero pensarci due volte, anche tre volte, prima di salvare i tempi nel database in un formato non UTC.

Nota
Non dimenticare di riavviare il server Rails dopo la modifica application.rb.


Ricorda che config.active_record.default_timezonepossono assumere solo due valori

  • : local (converte nel fuso orario definito in config.time_zone)
  • : utc (converte in UTC)

Ecco come puoi trovare tutti i fusi orari disponibili

rake time:zones:all

5
Questa sembra la risposta più completa / accurata - @Omnipresent
Aegix,

2
Questa dovrebbe essere la risposta accettata. È più completo.
Tenda Enrique Moreno

@ Mihai-AndreiDinculescu Pensi che sia meglio archiviare i datetimevalori in UTC nel database e poi cambiarli nel frontend come con moment.jso cosa suggerisci per mostrare questi dati nel fuso orario corretto per qualsiasi utente?
alexventuraio

@AlexVentura Sì, la gente più intelligente di me ha concordato molto tempo fa che la memorizzazione delle date in UTC è il modo migliore per andare.
Mihai-Andrei Dinculescu,

Si Ho capito. Ma cosa suggerisci di implementare nelle viste delle rotaie per mostrare i valori corretti per qualsiasi utente con fuso orario diverso?
alexventuraio,

187

aggiungendo seguito alle application.rbopere

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

59
Per me funziona così:config.time_zone = 'London' config.active_record.default_timezone = :local
Dean Perry,

41
Puoi vedere tutti i Fusi orari eseguendo questo in rails c-ActiveSupport::TimeZone.all.map(&:name)
Dean Perry

5
Grazie mille! Avevo lottato anche con questo. Ho un'app PHP legacy ereditata che interagisce con lo stesso database mysql e memorizza tutte le volte come locale; aggiornarlo per usare UTC non era un'opzione. Ciò che in precedenza non avevo realizzato nulla: config.time_zone = 'Central Time (US & Canada)' config.active_record.default_timezone = 'Central Time (US & Canada)' ma impostandolo sul: simbolo locale ha funzionato.
Matt Hucke,

8
Le guide dei binari dicono che config.active_record.default_timezonedovrebbe essere impostato solo su :localo :utc. Presumo che qualsiasi altra cosa avrebbe risultati inaspettati.
Kelvin,

2
Puoi vedere tutti i Fusi orari eseguendo questo inrake time:zones:all
Orlando

34

Sono arrivato alla stessa conclusione di Dean Perry dopo molta angoscia. config.time_zone = 'Adelaide'ed è config.active_record.default_timezone = :localstata la combinazione vincente. Ecco cosa ho trovato durante il processo.


5
Questa è la risposta giusta, default_timezone accetta solo: local o: utc
Francesco Belladonna,

20

Nel mio caso (Rails 5), ho finito per aggiungere queste 2 righe nel mio app/config/environments/development.rb

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

Questo è tutto! E per essere sicuro che Melbourne fosse letta correttamente, ho eseguito il comando nel mio terminale:

bundle exec rake time:zones:all

e Melbourne stava elencando nel fuso orario in cui mi trovo!


Cosa succede se desidero che tutti gli utenti visualizzino i valori di data e ora nel proprio fuso orario?
alexventuraio

@AlexVentura quando mostri i valori di data e ora ai tuoi utenti, convertili nei loro fusi orari. Rendere persistenti i record del database è una pratica migliore
Waheed

10

Se vuoi impostare il fuso orario su UTC a livello globale, puoi fare quanto segue in Rails 4:

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

Assicurati di riavviare l'applicazione o non vedrai le modifiche.


3

Su rotaie 4.2.2, vai a application.rbe usa config.time_zone='city'(ad esempio: "Londra" o "Bucarest" o "Amsterdam" e così via).

Dovrebbe funzionare bene. Ha funzionato per me.


3

Ho dovuto aggiungere questo blocco al mio environment.rbfile e tutto andava bene :)

Rails.application.configure do
    config.time_zone = "Pacific Time (US & Canada)"
    config.active_record.default_timezone = :local
end
  • L'ho aggiunto prima della rigaRails.application.initialize!

1

per l'utente cinese, basta aggiungere due righe di seguito config/application.rb:

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

0

In Ruby on Rails 6.0.1 vai su 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

Puoi vedere che sto configurando il fuso orario con 2 linee:

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

Spero che aiuti coloro che stanno lavorando con Ruby su Rails 6.0.1


-2

Se si desidera impostare l'ora locale, aggiungere il seguente testo 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

Quindi riavviare il server


12
default_timezone accetta una delle due opzioni ..: local o: utc .. non accetta un fuso orario specifico, quindi non funzionerà .. devi impostare default_timezone su: local
Urkle
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.