2012-04-01 12 views
24

Potrzebuję obliczyć przesunięcie, w godzinach, danej strefy czasowej z UTC w Ruby. Ta linia kodu pracował dla mnie, a przynajmniej tak myślałem:Jak obliczyć przesunięcie, w godzinach, danej strefy czasowej z UTC w ruby?

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

Ale okazuje się, że wracał do mnie Standard offset, a nie DST offset. Tak na przykład, załóżmy

self.timezone = "America/New_York" 

Jeśli biegnę powyższej linii offset_in_hours = -5, -4, nie tak jak powinien, biorąc pod uwagę, że data jest dziś 1 kwietnia 2012.

Czy ktoś może mi doradzić jak obliczyć offset_in_hs z UTC podając prawidłowy ciąg TimeZone w Ruby, który uwzględnia zarówno standardowe oszczędności czasu, jak i czasu letniego?

Dzięki!


Aktualizacja

Oto wyjście z IRB. Należy pamiętać, że Nowy Jork jest 4 godziny za UTC, a nie 5, z powodu oszczędności Dzienne:

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

To sugeruje, że jest to błąd w tzinfo lub nie jest DST-świadomy


Aktualizacja 2

W komentarzach do joelparkerhender błąd w powyższym kodzie polega na tym, że korzystałem z utc_offset, a nie utc_total_offset.

Zatem za mojego pierwotnego pytania, prawidłowa linia kodu:

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

Odpowiedz

52

Tak, użyj tzinfo tak:

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

Aby uzyskać bieżący okres:

current = tz.current_period 

Aby sprawdzić, czy jest dostępny czas letni:

current.dst? 
#=> true 

Aby baza przesunięcie strefy czasowej od UTC w sekundach:

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

Aby uzyskać oszczędności dzienne offsetowych od standardowego czasu:

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

aby uzyskać całkowite przesunięcie od UTC:

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

Całkowite przesunięcie od czasu UTC jest równe utc_offset + std_offset.

Jest to przesunięcie względem czasu lokalnego, w którym obowiązuje czas letni, w sekundach.

+0

Pomóż mi zrozumieć - czy current_period jest świadomy przez dst? że czas letni jest aktywny lub nieaktywny, to dlaczego current_period.offset nie bierze tego pod uwagę? Czy to błąd? W końcu wiem o tych wszystkich metodach w Time Zone, moim celem jest przypisanie poprawnej wartości zmiennej offset_in_hours – esilver

+0

Proszę zobaczyć moje wyjście powyżej, od uruchomienia irb - to sugeruje, że tzinfo nie jest w rzeczywistości dst-świadomy, lub że jest błąd? – esilver

+0

Nie błąd - wystarczy podać konto dst. Dodałem informacje do odpowiedzi na temat dwóch innych metod, które pokazują, jak to zrobić. – joelparkerhenderson

Powiązane problemy