ActiveSupport::TimeWithZone を使用して UTC をユーザー定義のタイムゾーンに変換する
概要
Rake タスクの一部として、UTC 時間をユーザーのタイムゾーンの同等の時間に変換する必要があります。私がやりたいのは、UTC タイムスタンプを午前 0 時に変更し、ユーザーのタイムゾーンで午前 0 時になるようにタイムスタンプを再作成することです。
UTC 時間を変換する
Wed, 01 Mar 2017 00:00:00 UTC +00:00
夏時間 (春/夏) を適用する場合は、東部夏時間 (EDT) まで
Wed, 01 Mar 2017 04:00:00 UTC +00:00
zone = ActiveSupport::TimeZone.new("Eastern Time (US & Canada)")
time = "Wed, 01 Mar 2017 00:00:00 UTC +00:00"
time.in_time_zone(zone)
=> Tue, 28 Feb 2017 19:00:00.000000000 EST -05:00
Rails はすべてのタイムスタンプを UTC に変換し直すため、上記の内容はデータベースに Wed, 01 Mar 2017 00:00:00 UTC +00:00 として保存されます。ただし、ユーザーのタイムゾーンでの本当の 1 日の始まりであるため、2017 年 3 月 1 日水曜日 04:00:00 UTC +00:00 を取得する必要があります。
解決策
ActiveSupport::TimeZone#parse を使用して、タイムゾーンに関連する文字列を解析できます。 「UTC +00:00」のようなタイムゾーン指定子は必ず省略してください。
zone = ActiveSupport::TimeZone.new("Eastern Time (US & Canada)")
time = zone.parse("Wed, 01 Mar 2017 00:00:00")
#=> Wed, 01 Mar 2017 00:00:00.000000000 EST -05:00
time.utc
#=> 2017-03-01 05:00:00 UTC
utc への最後の呼び出しは説明のみを目的としており、Rails はデータベースの時間を節約するときにこの変換を自動的に実行します。
数値入力の場合:
time = zone.local(2017, 3, 1)
#=> Wed, 01 Mar 2017 00:00:00.000000000 EST -05:00