Jak zmienić strefę czasową z DateTime w Rubim?


Czytanie, pisanie i serializowanie dat i godzin przy zachowaniu stałej strefy czasowej staje się denerwujące. Używam Ruby (i Rails 3.0) i próbuję zmienić strefę czasową DateTime. (w UTC), ale nie sam czas.
Chcę to:
t = DateTime.now
t.hour
-> 4
t.offset = 0
t.hour
-> 4
t.utc?
-> true

To jest najbliższe, do którego doszedłem, ale nie jest to intuicyjne.
t = DateTime.now
t.hour
-> 4
t += t.offset
t = t.utc
t.hour
-> 4
t.utc?
-> true

Czy jest lepszy sposób?
Zaproszony:
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Używając Rails 3, szukasz DateTime.change ()
dt = DateTime.now
=> Mon, 20 Dec 2010 18:59:43 +0100
dt = dt.change(:offset => "+0000")
=> Mon, 20 Dec 2010 18:59:43 +0000
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

d = DateTime.now
puts [ d, d.zone ]
#=> 2010-12-17T13:28:29-07:00
#=> -07:00d2 = d.new_offset(3.0/24)
puts d2, d2.zone
#=> 2010-12-17T23:28:29+03:00
#=> +03:00


Edit
: Ta odpowiedź nie uwzględnia informacji podanych w komentarzu do drugiej odpowiedzi, że chciałoby się, aby zgłaszane „godziny” były takie same po zmianie strefy czasowej.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Użycie przesunięcia liczbowego, takiego jak „+1000”, nie będzie działać przez cały rok ze względu na czas letni. Sprawdzanie ActiveSupport :: TimeZone.

Więcej informacji tutaj
https://coderoad.ru/2695837/
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Zamiast tego użyłbym obiektu

czas
http://ruby-doc.org/core/classes/Time.html... Więc pobierz aktualny czas lokalny, a następnie zwiększ go o przesunięcie czasu UTC i przekonwertuj na UTC, na przykład:
t = Time.now # or Time.parse(myDateTime.asctime)
t # => Thu Dec 16 21:07:48 -0800 2010
(t + t.utc_offset).utc # => Thu Dec 16 21:07:48 UTC 2010

Chociaż, zgodnie z komentarzem Phrogza, jeśli chcesz tylko przechowywać znaczniki czasu niezależnie od lokalizacji, po prostu użyj aktualnego czasu UTC:
Time.now.utc
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

w jaki sposób


wskazany przez @Sam, zmiana offsetu nie wystarczy i spowoduje błędy. Aby zapewnić odporność na ulepszenia zegara czasu letniego, konwersję należy wykonać w następujący sposób:
d = datetime_to_alter_time_zone
time_zone = 'Alaska'DateTime.new
.in_time_zone(time_zone)
.change(year: d.year, month: d.month, day: d.day, hour: d.hour, min: d.min, sec: d.sec)
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Jeśli ktoś (taki jak ja) ma

strefa czasowa w formacie ciągu, np. „Czas pacyficzny (Stany Zjednoczone i Kanada)”

To najlepszy sposób, jaki znalazłem:
<pre class="lang-rb prettyprint-override">
datetime.change(ActiveSupport::TimeZone[time_zone_string].formatted_offset(false))
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Możesz określić strefę czasową, której chcesz używać w swojej aplikacji, dodając następujący wiersz do pliku konfiguracyjnego (config/application.rb):
config.time_zone = 'Mumbai'
Oficjalną dokumentację w tej sprawie można znaleźć tutaj:

http://api.rubyonrails.org/cla ... .html
http://api.rubyonrails.org/cla ... .html
Inną opcją jest ustawienie „Monkey Patch” klasy „DateTime”.

Aby odpowiedzieć na pytania, Zaloguj się lub Zarejestruj się