Railsで時間をあるタイムゾーンから別のタイムゾーンに変換する


105

私のcreated_atタイムスタンプはUTCに保存されています:

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

それらの1つを(夏時間を考慮して)「東部標準時(米国およびカナダ)」に変換するにはどうすればよいですか?何かのようなもの:

Annotation.last.created_at.in_eastern_time

回答:


191

DateTimeクラスのin_time_zoneメソッドを使用する

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

あなたの特定の例のために

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

7
または、時間IDを使用することもできますnow.in_time_zone(3)
fl00r

8
created_at.in_time_zone("EST")より短い
オーランド

51
"EST" = "東部標準時"なので、夏時間の間は正しくありません。「東部標準時(米国およびカナダ)」は、DSTかどうかを判断します。
jhiro009 2012

1
in_time_zoneメソッドはActiveSupportの一部であるため、Railsに組み込まれていますが、Ruby stdlibの一部ではないことに注意してください。Railsアプリがあれば問題ありません。まっすぐなRubyアプリを持っている場合は、積極的なサポートを必ず要求する必要があります。
Gayle

このメソッドのドキュメントへのリンクはこちらです:apidock.com/rails/DateTime/in_time_zone
Naved Khan

17

これは古い質問ですが、何か言及する価値があります。で、前の回答には、一時的にタイムゾーンを設定するためにbefore_filterを使用することを示唆しています。

Time.zoneは情報をスレッドに格納しているためこのようなことは絶対に行わないでください。そのスレッドが処理する次のリクエストにリークする可能性があります。

代わりに、around_filterを使用して、リクエストの完了後にTime.zoneが確実にリセットされるようにする必要があります。何かのようなもの:

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

これについての詳細を読むここで


1
今日では、素晴らしいTime.use_zoneメソッドがあります。
freemanoid 2017

9

これをあなたに追加した場合 /config/application.rb

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

その後、あなたは携帯することができます

Annotation.last.created_at.in_time_zone

指定されたタイムゾーンの時刻を取得します。


application.rbでタイムゾーンを設定している場合、「。in_time_zone」を呼び出す必要はありません。jystがAnnotation.last.created_atを呼び出す必要があるため、レールは自動的にそれを実行します
Vishal

3

構成する場合 /config/application.rb

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

Time.now.in_time_zone

DateTime.now.in_time_zone

2

タイムゾーンを東部時間に設定します。

デフォルトのタイムゾーンはconfig / environment.rbで設定できます

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

これで、プルしたすべてのレコードがそのタイムゾーンになります。異なるタイムゾーンが必要な場合、たとえばユーザーのタイムゾーンに基づいて、コントローラーのbefore_filterで変更できます。

class ApplicationController < ActionController::Base

  before_filter :set_timezone

  def set_timezone
    Time.zone = current_user.time_zone
  end
end

すべての時間をUTCとしてデータベースに保存していることを確認してください。


雑種、シン、パッセンジャーなどのアプリケーションサーバーを実行している場合、これは問題になりますか?彼らは複数のインスタンスを実行しており、シングルスレッド化されていると思いますか?私は間違っているかもしれません、知りたいです!
nitecoder、

4
Time.zone=スレッドセーフなgithub.com/rails/rails/blob/master/activesupport/lib/…です。
LEST

それは'09にはなかったのでしょうか?
nitecoder、2012

2
@jpwynn:これによると:github.com/rails/rails/commit/…5年以上スレッドセーフです。あなたの問題のソースまたは例はありますか?
Pascal 2013年

1
スレッドは複数のセッションを処理できます。ユーザーがログインするときに一度設定すると、たとえば、最後にログインするユーザーが、同じスレッドを使用するセッションを持つすべてのユーザーのタイムゾーンを設定します。したがって、ページの読み込みごとにすべてのユーザーに設定するには、before_filterを使用する必要があります。
jpw 2013年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.