Rails: przekonwertuj UTC DateTime na inną strefę czasową

Odpowiedzi:

206
time.in_time_zone(time_zone)

Przykład:

zone = ActiveSupport::TimeZone.new("Central Time (US & Canada)")
Time.now.in_time_zone(zone)

Lub tylko

Time.now.in_time_zone("Central Time (US & Canada)")

Możesz znaleźć nazwy stref czasowych ActiveSupport, wykonując:

ActiveSupport::TimeZone.all.map(&:name)
# or for just US
ActiveSupport::TimeZone.us_zones.map(&:name)
mckeed
źródło
W irb, kiedy próbuję Time.now.in_time_zone ('CST'), otrzymuję błąd „undefined method 'in_time_zone'”. Czy istnieją klasy rails, których potrzebuję, aby to działało?
Drew Johnson
Z której wersji Railsów korzystasz? Czy to działa, jeśli wykonasz Time.zone.now.in_time_zone (...)?
mckeed
13
Aby użyć tego poza Railsami, require 'active_support/time'najpierw.
sunaku
3
Możesz wyświetlić listę wszystkich stref czasowych, uruchamiając rake time:zones:all. Zobacz także rake -D time. Ustaw domyślną strefę czasową w config/application.rb.
user664833,
1
@AdamEberlin W Railsach zazwyczaj używasz ActiveSupport :: TimeWithZone, a nie DateTime. Cały ten kod działa na ruby ​​obiektach DateTime oraz obiektach Time.
mckeed
6

jeśli Time.zonejest to Twoja żądana strefa czasowa, możesz użyć@date.to_time.to_datetime

> @date
=> Tue, 02 Sep 2014 23:59:59 +0000
> @date.class
=> DateTime
> @date.to_time
=> 2014-09-02 12:59:59 -1100
> @date.to_time.to_datetime
=> Tue, 02 Sep 2014 12:59:59 -1100 
vladCovaliov
źródło
Nie działa na Railsach 5 `Time.zone # => Europe / Paris my_date # => Wed, 29 Mar 2017 19:00:20 +0200 my_date.to_time # =>" 2017-03-29T17: 00: 20.000+ 00:00 "my_date.to_time.to_datetime # => środa, 29 marca 2017 17:00:20 +0000`
Cyril Duchon-Doris
5

W zwykłym rubinie, tylko z require 'date'użyciem new_offsetmetody:

require 'date'

d=DateTime.parse('2000-01-01 12:00 +0200')
l=d.new_offset('-0700')
u=l.new_offset('UTC')
puts "#{u.strftime('%a %F %T %Z')} ❖ #{l.strftime('%a %F %T %Z')}"

Testowano z Ruby 2.3.7, który był standardowo w systemie Mac OS X 10.13.

jbyler
źródło
3

Wypróbuj obiekty TimeWithZone firmy ActiveSupport manipulowane za pomocą TimeZone. ActiveSupport zapewnia również metodę in_time_zone do konwersji czasu UTC na określoną strefę czasową TimeZone. Odpowiedź McKeeda pokazuje kod.

Fred
źródło
Jaka jest składnia importowania TimeWithZone do mojej klasy? Czy mogę to zrobić domyślnie w Railsach?
Drew Johnson
1
Wierzę, że otrzymujesz to domyślnie. mckeed ma kod, którego potrzebujesz, ale nie zobaczysz go w irb. Musisz go uruchomić w Railsach.
Fred
Masz rację - dzięki, Fred - domyślnie jest dostarczany z Railsami. Chwytałem się słomek, próbując zmusić je do pracy w irbie.
Drew Johnson
3

Na wszelki wypadek, jeśli masz do czynienia z obiektem ActiveRecord w Railsach.

Dobrym pomysłem może być użycie Time.use_zonestrefy czasowej na żądanie, która zastępuje domyślną strefę czasową ustawioną wconfig.time_zone

Więcej szczegółów wyjaśniam na https://stackoverflow.com/a/25055692/542995

zdk
źródło
0

Używam simple_form w Rails 4 i właśnie dodałem pole wejściowe jako

<%= f.input :time_zone, :as => :time_zone %>

z migracją

class AddTimeZoneColumnToTextmessage < ActiveRecord::Migration
  def change
    add_column :textmessages, :time_zone, :string
  end
end
maudulus
źródło
1
To nie odpowiada na pytanie, jak konwertować obiekty DateTime
zykadelic