2012-04-01 12 views
24

Necesito calcular el desplazamiento, en horas, de una zona horaria dada desde UTC en Ruby. Esta línea de código había estado trabajando para mí, o así que pensé:¿Cómo calculo el desplazamiento, en horas, de una zona horaria dada de UTC en ruby?

offset_in_hours = (TZInfo::Timezone.get(self.timezone).current_period.offset.utc_offset).to_f/3600.0 

Pero, resulta que estaba volviendo a mí el desplazamiento estándar, no el desplazamiento de DST. Así, por ejemplo, asumir

self.timezone = "America/New_York" 

Si funciono con la línea anterior, offset_in_hours = -5, -4, no como debe ser, dado que la fecha de hoy es 1 de abril de 2012.

¿Alguien puede aconsejarme cómo calcular offset_in_hours desde UTC con una cadena válida TimeZone en Ruby que tenga en cuenta el horario estándar y el horario de verano?

Gracias!


actualización

Aquí es un poco de salida del IRB. Tenga en cuenta que Nueva York es de 4 horas detrás de GMT, no 5, debido a los cambios de horario:

>> require 'tzinfo' 
=> false 
>> timezone = "America/New_York" 
=> "America/New_York" 
>> offset_in_hours = TZInfo::Timezone.get(timezone).current_period.utc_offset/(60*60) 
=> -5 
>> 

Esto sugiere que hay un error en tzinfo o no se DST-conscientes


actualización 2

por los comentarios de joelparkerhender, el error en el código anterior es que yo estaba usando utc_offset, no utc_total_offset.

Por lo tanto, por mi pregunta original, la línea correcta de código es:

offset_in_hours = (TZInfo::Timezone.get(self.timezone).current_period.offset.utc_total_offset).to_f/3600.0 

Respuesta

52

Sí, utilice tzinfo así:

require 'tzinfo' 
tz = TZInfo::Timezone.get('America/Los_Angeles') 

Para obtener el período actual:

current = tz.current_period 

Para saber si el horario de verano está activo:

current.dst? 
#=> true 

para obtener la base desplazamiento de la zona horaria a UTC en segundos:

current.utc_offset 
#=> -28800 which is -8 hours; this does NOT include daylight savings 

para conseguir el ahorro de luz de compensación de tiempo estándar:

current.std_offset 
#=> 3600 which is 1 hour; this is because right now we're in daylight savings 

para obtener el total desplazamiento de UTC:

current.utc_total_offset 
#=> -25200 which is -7 hours 

La compensación total de UTC es igual a utc_offset + std_offset.

Este es el desplazamiento de la hora local donde está en efecto el horario de verano, en segundos.

+0

Ayúdame a comprender - si current_period es consciente a través de dst? ese horario de ahorro de energía está activo o inactivo, entonces ¿por qué current_period.offset no toma eso en consideración? ¿Es esto un error? En definitiva, conozco todos estos métodos en TimeZone, mi objetivo es asignar el valor correcto a la variable offset_in_hours – esilver

+0

Consulte mi resultado anterior, desde la ejecución de irb: esto sugiere que tzinfo no está, de hecho, dst-aware, o que hay un error? – esilver

+0

No es un error, solo necesita dar cuenta del dst. Agregué información a la respuesta sobre dos métodos más que muestran cómo hacerlo. – joelparkerhenderson

Cuestiones relacionadas