2009-09-06 15 views
90

miei created_at timestamp sono memorizzati in UTC:convertire il tempo da un fuso orario all'altro in Rails

>> Annotation.last.created_at 
=> Sat, 29 Aug 2009 23:30:09 UTC +00:00 

Come posso convertire uno di loro a 'Eastern Time (US & Canada)' (prendendo in considerazione la luce del giorno risparmio)? Qualcosa di simile:

Annotation.last.created_at.in_eastern_time 

risposta

159

Utilizzare il metodo in_time_zone della classe DateTime

Loading development environment (Rails 2.3.2) 
>> now = DateTime.now.utc 
=> Sun, 06 Sep 2009 22:27:45 +0000 
>> now.in_time_zone('Eastern Time (US & Canada)') 
=> Sun, 06 Sep 2009 18:27:45 EDT -04:00 
>> quit 

Così, per esempio, il vostro particolare

Annotation.last.created_at.in_time_zone('Eastern Time (US & Canada)') 
+6

oppure si può semplicemente utilizzare un'ora ident 'now.in_time_zone (3)' ' – fl00r

+7

created_at.in_time_zone ("EST") 'è più breve – Orlando

+40

"EST"= "Eastern standard Time", quindi sarà storto durante l'ora legale. "Eastern Time (USA e Canada)" capisce se si tratta di DST o no per te. – jhiro009

2

Imposta il tuo fuso orario a Eastern Time.

È possibile impostare il fuso orario predefinito in config/environment.rb

config.time_zone = "Eastern Time (US & Canada)" 

Ora tutti i record si tira fuori sarà in quel fuso orario. Se hai bisogno di fusi orari diversi, ad esempio in base al fuso orario dell'utente, puoi modificarlo con un before_filter nel controller.

class ApplicationController < ActionController::Base 

    before_filter :set_timezone 

    def set_timezone 
    Time.zone = current_user.time_zone 
    end 
end 

Assicurati solo di memorizzare tutti i tuoi tempi nel database come UTC e tutto sarà dolce.

+2

Eviterei 'Time.zone = ..'come non è thread-safe. – gertas

+0

Questo problema è necessario se si esegue un server delle applicazioni come bastardo, passeggero o passeggero? Corrono più di un'istanza, credo che sia una singola discussione? Potrei sbagliarmi, mi piacerebbe saperlo! – nitecoder

+4

'Time.zone =' è thread-safe https://github.com/rails/rails/blob/master/activesupport/lib/active_support/core_ext/time/zones.rb#L36-38. – lest

8

se si aggiunge questo al vostro /config/application.rb

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

Poi si può cella

Annotation.last.created_at.in_time_zone 

per ottenere il tempo nel fuso orario specificato.

14

Anche se questa è una vecchia questione, è degno di nota qualcosa. In un previous reply si suggerisce di utilizzare un before_filter per impostare il fuso orario temporalmente.

È necessario mai, mai fare ciò perché Time.zone memorizza le informazioni nel thread e probabilmente si verificherà una perdita alla richiesta successiva gestita da quel thread.

Invece si dovrebbe usare un around_filter per assicurarsi che il Time.zone viene azzerato dopo la richiesta è stata completata. Qualcosa di simile:

around_filter :set_time_zone 

private 

def set_time_zone 
    old_time_zone = Time.zone 
    Time.zone = current_user.time_zone if logged_in? 
    yield 
ensure 
    Time.zone = old_time_zone 
end 

Ulteriori informazioni su questo here

+0

C'è un bel metodo [Time.use_zone] (https://apidock.com/rails/Time/use_zone/class) al giorno d'oggi. – freemanoid

2

Se si configura il /config/application.rb

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

Time.now.in_time_zone 

DateTime.now.in_time_zone 
Problemi correlati