2010-05-28 10 views
25

In ruby, come posso ottenere l'ora corrente in un determinato fuso orario? Conosco lo scostamento da UTC e voglio ottenere l'ora corrente nel fuso orario con quell'offset.ruby ​​get Time in un determinato fuso orario

+0

prega di fare riferimento a quello che ho postato https://stackoverflow.com/questions/24577449/convert-time-to-other-timezone/44278155#44278155 –

risposta

-2

Basta aggiungere o sottrarre il numero appropriato di secondi:

 
>> utc = Time.utc(2009,5,28,10,1)   # given a utc time 
=> Thu May 28 10:01:00 UTC 2009 
>> bst_offset_in_mins = 60     # and an offset to another timezone 
=> 60 
>> bst = t + (bst_offset_in_mins * 60)  # just add the offset in seconds 
=> Thu May 28 11:01:00 UTC 2009    # to get the time in the new timezone 
+0

Nota: Stai ancora restituire un tempo UTC, solo è stato compensato, il che causerà ogni sorta di stranezza se proverai a confrontare i tempi. Un buon test di questo è se i due sono uguali o meno. – yaauie

+0

Questo ha risolto il mio problema, grazie @stephenr! –

+0

Impressionante, sembra fondamentalmente è Time.now + = number_of_seconds, thx! – rogerdpack

15

userei il ActiveSupport gemma:

require 'active_support/time' 
my_offset = 3600 * -8 # US Pacific 

# find the zone with that offset 
zone_name = ActiveSupport::TimeZone::MAPPING.keys.find do |name| 
    ActiveSupport::TimeZone[name].utc_offset == my_offset 
end 
zone = ActiveSupport::TimeZone[zone_name] 

time_locally = Time.now 
time_in_zone = zone.at(time_locally) 

p time_locally.rfc822 # => "Fri, 28 May 2010 09:51:10 -0400" 
p time_in_zone.rfc822 # => "Fri, 28 May 2010 06:51:10 -0700" 
+2

quando ho installato il gem di active_support, avevo bisogno di richiedere 'active_support/time' per far funzionare correttamente il tuo esempio. –

+0

+1 - Questo è stato molto molto utile. Molte grazie. –

3

Un modo più semplice per farlo è quello di passare semplicemente l'offset (in modulo intero) per l'hash ActiveSupport :: fuso orario:

ActiveSupport::TimeZone[-8] 
=> #<ActiveSupport::TimeZone:0x7f6a955acf10 @name="Pacific Time (US & Canada)", @tzinfo=#<TZInfo::TimezoneProxy: America/Los_Angeles>, @utc_offset=nil, @current_period=#<TZInfo::TimezonePeriod: #<TZInfo::TimezoneTransitionInfo: #<TZInfo::TimeOrDateTime: 1320570000>,#<TZInfo::TimezoneOffsetInfo: -28800,0,PST>>,#<TZInfo::TimezoneTransitionInfo: #<TZInfo::TimeOrDateTime: 1331460000>,#<TZInfo::TimezoneOffsetInfo: -28800,3600,PDT>>>> 
9

per un UTC offset x ore, il cu tempo rrent può essere calcolato con l'aiuto di ActiveSupport in Rails, come gli altri hanno detto:

utc_offset = -7 
zone = ActiveSupport::TimeZone[utc_offset].name 
Time.zone = zone 
Time.zone.now 

o al posto delle due linee

DateTime.now.in_time_zone(zone) 

Oppure, se non si dispone di Rails, si può anche utilizzare new_offset per convertire un DateTime individuare un altro fuso orario

utc_offset = -7 
local = DateTime.now 
local.new_offset(Rational(utc_offset,24)) 
+0

Questa dovrebbe essere considerata la risposta reale in quanto include una soluzione puramente a base di rubini. –

+0

Perché non l'ho trovato prima ?! 'DateTime.now.in_time_zone (zone)' Così semplice è bello – rorykoehler

0

ho provato un gem install active_support, ha installato ActiveSupport-3.00, che mi ha dato un errore:

"Non hai installato tzinfo nella tua applicazione. Si prega di aggiungerlo al tuo Gemfile ed eseguire l'installazione del pacchetto "

tzinfo è un gioiello che ActiveSupport utilizza - era un po 'più pulito per i miei scopi, non ha alcuna dipendenza esterna - il lato negativo è che sembra di lasciare tutto ciò che sembra essere UTC, quindi se vuoi che i tuoi fusi orari siano corretti, lo installerà tutto ciò di cui hai bisogno Sto includendo questa risposta principalmente per riferimento ad altri che si trovano nello stesso problema/googlability

(usare gem install tzinfo) per installare la gemma

require 'tzinfo' 
zone = TZInfo::Timezone.get('US/Eastern') 
puts zone.now 

ci sono un certo numero di modi diversi per ottenere i fusi orari, ma si può vedere un elenco utilizzando

TZInfo::Timezone.all 
24

Una soluzione più semplice, più leggero:

Time.now.getlocal('-08:00') 

ben documentato here.

Aggiornamento 2017.02.17: Se hai un fuso orario e volete trasformarla in un offset è possibile utilizzare con #getlocal comprensivo di DST, Ecco un modo per farlo:

require 'tzinfo' 

timezone_name = 'US/Pacific' 

timezone = TZInfo::Timezone.get(timezone_name) 
offset_in_hours = timezone.current_period.utc_total_offset_rational.numerator 
offset = '%+.2d:00' % offset_in_hours 

Time.now.getlocal(offset) 

Se si vuole fare questo per momenti diverso #now, si dovrebbe studiare sul Ruby Time class, particolarmente Time#gm e Time#local, e il Ruby TZInfo classes, particolarmente TZInfo::Timezone.get e TZInfo::Timezone#period_for_local

+0

La migliore, la risposta più semplice. Non richiede né gemme. Dovrebbe essere controllato come soluzione. Stavo controllando i documenti come afferrare una zona di cambio diurno, btw. Come gli Stati Uniti Pacific Time: a volte '-08: 00', a volte '-07: 00'. – Marcos

+0

Si interrompe quando l'ora legale. – avguchenko

+0

L'interrogante originale ha chiesto degli offset e specificato Ruby, non Rails. Gli offset sono molto più semplici dei fusi orari proprio a causa dei problemi di osservanza dell'ora legale. Questo è il motivo per cui esiste un fuso orario separato per l'Indiana, ad esempio. Se vuoi gestire i fusi orari in Ruby, inizia leggendo [questo post del blog] (http://rpanachi.com/2016/07/04/ruby-is-time-to-talk-about-timezones#using -tzinfo) per capire come gestirli. Detto questo, ecco un one-liner schifoso per trasformare tz in offset compreso DST: ''% +. 2d: 00'% (TZInfo :: Timezone.get ('US/Pacific'). Current_period.utc_total_offset/3600)' –

3
gem install tzinfo 

Poi

require 'tzinfo' 

tz = TZInfo::Timezone.get('US/Pacific') 
Time.now.getlocal(tz.current_period.offset.utc_total_offset) 
Problemi correlati