2010-05-28 11 views
25

En ruby, ¿cómo puedo obtener la hora actual en una zona horaria determinada? Sé el desplazamiento de UTC, y quiero obtener la hora actual en la zona horaria con ese desplazamiento.ruby ​​get Tiempo en la zona horaria dada

+0

Consulte la que he publicado https://stackoverflow.com/questions/24577449/convert-time-to-othertimetime/44278155#44278155 –

Respuesta

-2

Sólo tiene que añadir o restar el número apropiado de segundos:

 
>> 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: Todavía está devolviendo una hora UTC, simplemente ha sido compensado, lo que causará todo tipo de rareza si intenta comparar los tiempos. Una buena prueba de esto es si los dos siguen siendo iguales o no. – yaauie

+0

Esto resolvió mi problema, gracias @stephenr! –

+0

Impresionante, parece que básicamente es Time.now + = number_of_seconds, thx! – rogerdpack

15

que haría uso de la ActiveSupport joya:

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

cuando instalé la gema active_support, necesitaba requerir 'active_support/time' para que su ejemplo funcione correctamente. –

+0

+1 - Esto fue muy, muy útil. Muchas gracias. –

3

Una forma más fácil de hacerlo es simplemente pasar el offset (en forma número entero) para el hash ActiveSupport :: Zona horaria:

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

para una UTC desplazamiento de x horas, la cu tiempo rrent se puede calcular con la ayuda de ActiveSupport en Rails, como los demás decían:

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

o en lugar de las dos líneas

DateTime.now.in_time_zone(zone) 

O, si usted no tiene rieles, también se puede new_offset utilizar para convertir un DateTime localizar a otra zona horaria

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

Esto se debe considerar la respuesta real, ya que incluye una solución puramente basada en ruby. –

+0

¿Por qué no encontré esto antes? 'DateTime.now.in_time_zone (zone)' Tan simple que es hermoso – rorykoehler

0

probé un gem install active_support, instalado ActiveSupport-3.00, lo que me dio un error:

"No tiene instalado tzinfo en su aplicación. Por favor agréguelo a su Gemfile y ejecute la instalación del paquete "

tzinfo es una joya que usa ActiveSupport - fue un poco más limpio para mis propósitos, no tiene dependencias externas - el inconveniente es que parece que se va todo parece que es UTC, así que si quieres que tus zonas horarias se vean correctas, gem install activerecord instalará todo lo que necesites. Estoy incluyendo esta respuesta como referencia para otras que tengan el mismo problema/googlability.

(uso gem install tzinfo) para instalar la gema

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

hay una serie de diferentes maneras de conseguir las zonas horarias, pero se puede ver una lista con

TZInfo::Timezone.all 
24

Una solución más simple, más ligero:

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

bien documentado here.

Actualización 2017.02.17: Si usted tiene una zona horaria y desea convertir eso en un desplazamiento que puede utilizar con #getlocal incluido el horario de verano, aquí es una manera de hacerlo:

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) 

Si quieres hacer esto por momentos aparte de #now, debe estudiar hasta en la Ruby Time class, particularmente Time#gm y Time#local y la Ruby TZInfo classes, particularmente TZInfo::Timezone.get y TZInfo::Timezone#period_for_local

+0

Mejor, la respuesta más simple. No requiere ni gemas. Debe verificarse como solución. Estaba comprobando los documentos cómo agarrar una zona de cambio de luz del día, por cierto. Como la hora del Pacífico de EE. UU .: a veces '-08: 00', a veces '-07: 00'. – Marcos

+0

Esto se rompe cuando el horario de verano. – avguchenko

+0

El interlocutor original preguntó por las compensaciones y especificó Ruby, no Rails. Las compensaciones son mucho más simples que las zonas horarias, precisamente debido a problemas de observancia DST. Esta es la razón por la cual hay una zona horaria separada para Indiana, por ejemplo. Si desea ocuparse de las zonas horarias en Ruby, comience por leer [esta publicación del blog] (http://rpanachi.com/2016/07/04/ruby-is-time-to-talk-about-timezones#using -tzinfo) para entender cómo tratar con ellos. Dicho esto, aquí hay un anticuado para convertir a tz en offset, incluido DST: ''% + .2d: 00'% (TZInfo :: Timezone.get ('US/Pacific'). Current_period.utc_total_offset/3600)' –

3
gem install tzinfo 

Entonces

require 'tzinfo' 

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