Converti UTC in ora locale in Rails 3


95

Ho problemi a convertire l'ora UTC Timeo TimeWithZonel'ora locale in Rails 3.

Say momentè una Timevariabile in UTC (ad esempio moment = Time.now.utc). Come faccio a convertire momentnel mio fuso orario, prendendomi cura dell'ora legale (cioè utilizzando EST / EDT)?

Più precisamente, vorrei stampare "lunedì 14 marzo, 9 AM" se l'ora corrisponde a questa mattina alle 9 AM EDT e "lunedì 7 marzo, 9 AM" se l'ora era 9 AM EST di lunedì scorso.

Si spera che ci sia un altro modo?

Modifica : prima ho pensato che "EDT" dovrebbe essere un fuso orario riconosciuto, ma "EDT" non è un fuso orario effettivo, più simile allo stato di un fuso orario. Ad esempio, non avrebbe alcun senso chiedere Time.utc(2011,1,1).in_time_zone("EDT"). È un po 'confuso, poiché "EST" è un fuso orario effettivo, utilizzato in alcuni luoghi che non utilizzano l'ora legale e durano (UTC-5) un anno.

Risposte:


113

Rails ha i suoi nomi. Guardali con:

rake time:zones:us

Puoi anche correre rake time:zones:allper tutti i fusi orari. Per vedere altre attività di rake relative alla zona:rake -D time

Quindi, per convertire in EST, provvedere automaticamente all'ora legale:

Time.now.in_time_zone("Eastern Time (US & Canada)")

21
Come potresti utilizzare automaticamente il fuso orario per l'utente che accede all'app Web?
dmonopoly

L'unico modo che ho trovato è stato con Javascript e poi passarlo di nuovo al server. (new Date()).getTimeZoneOffset(). Ma è abbastanza incoerente, quindi questo ragazzo sembra aver scritto il suo: onlineaspect.com/2007/06/08/…
Duke

2
aggiunge automaticamente il fuso orario a tutti i datetimes di ActiveRecord - config.time_zone = 'Eastern Time (US & Canada)' - in config / application.rb
idrinkpabst

Aggiornamento: il proprietario della soluzione JS collegata indica una soluzione più recente: pellepim.bitbucket.org/jstz
Miles

@dmonopoly puoi impostare il fuso orario nella configurazione dell'applicazione config.time_zone = 'Wellington'e quindi utilizzare Time.current (che è equivalente a time.now ma ha utilizzato il fuso orario che hai impostato)
Sean

115

Time#localtime ti darà l'ora nel fuso orario corrente della macchina che esegue il codice:

> moment = Time.now.utc
  => 2011-03-14 15:15:58 UTC 
> moment.localtime
  => 2011-03-14 08:15:58 -0700 

Aggiornamento: se vuoi convertire a fusi orari specifici piuttosto che al tuo fuso orario, sei sulla strada giusta. Tuttavia, invece di preoccuparti di EST rispetto a EDT, passa semplicemente nel fuso orario orientale generale: saprà in base al giorno se è EDT o EST:

> Time.now.utc.in_time_zone("Eastern Time (US & Canada)")
  => Mon, 14 Mar 2011 11:21:05 EDT -04:00 
> (Time.now.utc + 10.months).in_time_zone("Eastern Time (US & Canada)")
  => Sat, 14 Jan 2012 10:21:18 EST -05:00 

È un inizio. Come posso impostare il fuso orario corrente (poiché non sono nemmeno sicuro di dove sarà ospitata l'app, il server potrebbe trovarsi in un fuso orario diverso da quello che dovrebbe essere utilizzato).
Marc-André Lafortune

6
Il metodo "localtime" è interessante, ma il fuso orario della macchina che esegue il codice non è utile quanto il fuso orario dell'utente che accede all'applicazione web. (Come accennato qui: stackoverflow.com/questions/6003491/rails-3-user-timezones/… ) Come potresti ottenere il fuso orario per l'utente che accede all'applicazione web?
dmonopoly

@daze Immagino che tu possa impostare un'opzione per i tuoi utenti per scegliere i loro fusi orari e quindi utilizzare il in_time_zonemetodo con il loro fuso orario.
Dylan Markow

1
Grazie, il metodo localtime è esattamente ciò di cui avevo bisogno.
Bob

Time.now.localtimefunziona su una normale sessione irb ma quando provo a eseguirlo su una macchina che si trova nel fuso orario UTC, non funziona.
Ava

15

È facile configurarlo utilizzando la zona locale del sistema, aggiungilo solo nella tua applicazione

config.time_zone = Time.now.zone

Quindi, rails dovrebbe mostrarti i timestamp nella tua ora locale oppure puoi usare qualcosa come questa istruzione per ottenere l'ora locale

Post.created_at.localtime

15

In realtà c'è una bella gemma chiamata local_timeda campo base per fare tutto questo solo sul lato client, credo:

https://github.com/basecamp/local_time


Funziona al meglio. Conosciamo già il tempo memorizzato, il modo per mostrarlo nel formato all'utente è meglio farlo sul lato client secondo me e questo lo fa.
Neeraj Shukla

1

Non so perché ma nel mio caso non funziona come suggerito in precedenza. Ma funziona così:

Time.now.change(offset: "-3000")

Ovviamente devi cambiare offsetvalore al tuo.


0

Se lo stai effettivamente facendo solo perché vuoi ottenere il fuso orario dell'utente, tutto ciò che devi fare è cambiare il tuo fuso orario in te config/applications.rb.

Come questo:

Rails, per impostazione predefinita, salverà il record del tempo in UTC anche se specifichi il fuso orario corrente.

config.time_zone = "Singapore"

Quindi questo è tutto ciò che devi fare e sei a posto.

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.