Rails'te Saati bir saat diliminden diğerine dönüştürme


105

Zaman created_atdamgalarım UTC olarak saklanıyor:

>> Annotation.last.created_at
=> Sat, 29 Aug 2009 23:30:09 UTC +00:00

Bunlardan birini 'Doğu Saati'ne (ABD ve Kanada)' nasıl dönüştürebilirim (gün ışığından yararlanma hesabını dikkate alarak)? Gibi bir şey:

Annotation.last.created_at.in_eastern_time

Yanıtlar:


191

DateTime sınıfının in_time_zone yöntemini kullanın

Loading development environment (Rails 2.3.2)
>> now = DateTime.now.utc
=> Sun, 06 Sep 2009 22:27:45 +0000
>> now.in_time_zone('Eastern Time (US & Canada)')
=> Sun, 06 Sep 2009 18:27:45 EDT -04:00
>> quit

Yani sizin özel örneğiniz için

Annotation.last.created_at.in_time_zone('Eastern Time (US & Canada)')

7
ya da sadece saat kimliği kullanabilirsiniznow.in_time_zone(3)
fl00r

8
created_at.in_time_zone("EST")daha kısa
Orlando

51
"EST" = "Doğu Standart Saati", bu nedenle Yaz Saati Uygulaması sırasında yanlış olacaktır. "Doğu Saati (ABD ve Kanada)" sizin için DST olup olmadığını anlar.
jhiro009

1
İn_time_zone yönteminin ActiveSupport'un bir parçası olduğunu ve bu nedenle Rails'e yerleşik olduğunu, ancak Ruby stdlib'inin bir parçası olmadığını unutmayın. Ray uygulamanız varsa sorun değil. Düz bir Ruby uygulamanız varsa, aktif desteğe ihtiyacınız olduğundan emin olmanız gerekir.
Gayle

Bu yöntemin belgelerine bağlantı burada: apidock.com/rails/DateTime/in_time_zone
Naved Khan

17

Bu eski bir soru olmasına rağmen, bir şeyden bahsetmeye değer. Bir de önceki cevapta da geçici olarak zaman dilimini ayarlamak için bir before_filter kullanmak önerilir.

You should asla, asla çünkü Time.zone bilgiyi iş parçacığında depolar ve muhtemelen bu iş parçacığı tarafından işlenen bir sonraki isteğe sızacaktır.

Bunun yerine, istek tamamlandıktan sonra Time.zone'un sıfırlandığından emin olmak için bir around_filter kullanmalısınız. Gibi bir şey:

around_filter :set_time_zone

private

def set_time_zone
  old_time_zone = Time.zone
  Time.zone = current_user.time_zone if logged_in?
  yield
ensure
  Time.zone = old_time_zone
end

Bununla ilgili daha fazlasını buradan okuyun


1
Günümüzde güzel bir Time.use_zone yöntemi var.
freemanoid

9

Bunu eklerseniz /config/application.rb

config.time_zone = 'Eastern Time (US & Canada)'

O zaman hücreye girebilirsin

Annotation.last.created_at.in_time_zone

saati belirtilen saat diliminde almak için.


application.rb'de saat dilimini yapılandırıyorsak, ".in_time_zone" çağrısına gerek yoktur. rails bunu bizim için otomatik olarak yapar jyst Annotation.last.created_at
Vishal

3

Yapılandırırsanız /config/application.rb

config.time_zone = 'Eastern Time (US & Canada)'

Time.now.in_time_zone

DateTime.now.in_time_zone

2

Saat diliminizi Doğu Saati olarak ayarlayın.

Varsayılan saat diliminizi config / environment.rb'de ayarlayabilirsiniz.

config.time_zone = "Eastern Time (US & Canada)"

Şimdi çıkardığınız tüm kayıtlar o saat diliminde olacak. Farklı saat dilimlerine ihtiyacınız varsa, örneğin bir kullanıcının saat dilimine göre bunu kontrol cihazınızdaki bir before_filter ile değiştirebilirsiniz.

class ApplicationController < ActionController::Base

  before_filter :set_timezone

  def set_timezone
    Time.zone = current_user.time_zone
  end
end

Sadece tüm zamanlarınızı UTC olarak veri tabanında sakladığınızdan emin olun ve her şey tatlı olacaktır.


Melez, ince veya yolcu gibi bir uygulama sunucusu çalıştırıyorsanız bu önemli mi? Birden fazla örnek çalıştırıyorlar, tek iş parçacıklı sanırım? Yanılıyor olabilirim, bilmek isterim!
nitecoder

4
Time.zone=iş parçacığı açısından güvenlidir github.com/rails/rails/blob/master/activesupport/lib/… .
diye

'09'da olmayabilir mi?
nitecoder

2
@jpwynn: buna göre: github.com/rails/rails/commit/… 5 yıldan beri Thread güvenlidir. Probleminiz için herhangi bir kaynak veya örnek var mı?
Pascal

1
Bir iş parçacığı birden fazla oturuma hizmet edebilir. Kullanıcı oturum açtığında bunu bir kez ayarlarsınız, örneğin oturum açacak SON kullanıcı, oturumu aynı iş parçacığını kullanan TÜM kullanıcılar için saat dilimini ayarlayacaktır. Bu nedenle, her sayfa yüklemesinde her kullanıcı için ayarlamak üzere bir before_filter kullanmanız GEREKİR.
jpw
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.