日々之迷歩

世の中わからんことだらけ

ITが複雑で難しくなっていく様に翻弄される日々です。微力ながら共著させていただいた「シェル・ワンライナー160本ノック」をよろしくお願い申し上げます。

RailsでRDBに書かれた時間のタイムゾーン

RailsRDBに保存された時間のタイムゾーンの扱いについて確認しました。以下のようなScheduleモデルについて考えます。

$ ruby script/generate scaffold schedule date:datetime
$ rake db:migrate


config/environment.rbにタイムゾーンUTC設定した場合(デフォルト)、RDBに保存される時刻情報はUTCになりました。ローカルなタイムゾーン(Asia/Tokyo)を得るには、ActiveSupport::TimeWithZone#localtimeメソッドを使います。

$ ruby script/console
Loading development environment (Rails 2.3.11)
>> Time.zone
 => #, @utc_offset=0> #【タイムゾーンがUTC】
>> s = Schedule.new
 => #
>> s.date = "2011-08-21 00:00:00"
 => "2011-08-21 00:00:00"
>> s.save
 => true
>> s = Schedule.first
 => #
>> s.date
 => Sun, 21 Aug 2011 00:00:00 UTC +00:00 #【タイムゾーンがUTCで保存】
>> s.date.class
 => ActiveSupport::TimeWithZone
>> s.date.localtime
 => Sun Aug 21 09:00:00 +0900 2011 #【タイムゾーンがTokyoになって+9時間される】
>> s.date.localtime.class
 => Time


config/environment.rbにzoneを"Tokyo"に設定した場合、RDBに保存される時刻情報は、タイムゾーンがAsia/Tokyo、UTCからのオフセットが+9時間になります。

$ rake db:drop
$ rake db:migrate
$ ruby script/console
Loading development environment (Rails 2.3.11)
>> Time.zone
 => #, @utc_offset=32400>【タイムゾーンがAsia/Tokyo、オフセットが+9時間】
>> s = Schedule.new
 => #
>> s.date = "2011-08-21 00:00:00"
 => "2011-08-21 00:00:00"
>> s.save
 => true
>> s = Schedule.first
 => #
>> s.date
 => Sun, 21 Aug 2011 00:00:00 JST +09:00 #【タイムゾーンがTokyoで保存】
>> s.date.class
 => ActiveSupport::TimeWithZone
>> s.date.localtime
 => Sun Aug 21 00:00:00 +0900 2011 #【タイムゾーンは変わらず】
>> s.date.localtime.class
 => Time


config/environment.rbのzone設定を削除した場合は、zoneを”Tokyo”に設定した時と同様になります。システムから情報を取って来ていると思われます。

$ rake db:drop
$ rake db:migrate
$ ruby script/console
Loading development environment (Rails 2.3.11)
>> Time.zone
 => nil #【タイムゾーンが設定されていない】
>> s = Schedule.new
 => #
>> s.date = "2011-08-21 00:00:00"
 => "2011-08-21 00:00:00"
>> s.save
 => true
>> s = Schedule.first
 => #
>> s.date
 => Sun Aug 21 00:00:00 +0900 2011 #【タイムゾーンがTokyoで保存】
>> s.date.class
 => Time
>> s.date.localtime
 => Sun Aug 21 00:00:00 +0900 2011 #【タイムゾーンは変わらず】
>> s.date.localtime.class
 => Time