&tag(Rails3/タイムゾーン); *目次 [#qbb98028] #contents *参考情報 [#ldf2611c] -[[Rails3]] -[[Ruby on RailsでタイムゾーンにJSTを使用する方法 - 戯言メイテル:http://d.hatena.ne.jp/iriya_0624/20130429/1367244830]] -[[Future Journal 〜未来志向で行こう〜:http://twodollarz.hatenablog.jp/]] -[[Rails3系のtimezoneの扱いに関するメモ - Qiita [キータ]:http://qiita.com/semind/items/68341489a9c5149b815d]] -[[Rails3 + ActiveRecord で正しくtimezoneを設定する - Future Journal 〜未来志向で行こう〜:http://twodollarz.hatenablog.jp/entry/20120703]] -[[Rails と時刻 - @kyanny's blog:http://blog.kyanny.me/entry/2012/08/16/042204]] *JSTで使用するす [#g1a754ed] *JSTで使用する [#g1a754ed] -DBにはUTCで保存するのが善き行いようのようだが、明らかに日本人しか使わないサービスの場合JSTで保存したほうがわかりやすい。 -config/application.rbを編集。 #pre{{ config.time_zone = 'Tokyo' config.active_record.default_timezone = :local }} *UTCで保存する [#g4f33b06] -[[Railsでの時間管理はUTCで | tamo's blog:http://tamosblog.wordpress.com/2013/01/16/rails_ut/]]にあるように、utcのまま使い、表示のときだけ変換する。 time.in_time_zone('Tokyo').strftime("%Y/%m/%d %H:%M:%S") *デモ [#ze4560d9] -config/applications.rbで、config.time_zoneとconfig.active_record.default_timezoneを切り替えてデータベースに保存される値と表示される値がどうなるか確認してみる。 **デモテーブルの作成 [#j406ccdb] -date1, date2, timestamp1を持つDemoItemsテーブルを生成 $ bundle exec rails generate model DemoItems date1:datetime date2:datetime timestamp1:timestamp -内容確認。created_at / updated_at などはmysqlのdatetimeにマッピングされている。このためMySQLのタイムゾーン自動変換は無視できることがわかる(timestamp型にしか影響しない)。 #pre{{ CREATE TABLE `demo_items` ( `id` int(11) NOT NULL AUTO_INCREMENT, `date1` datetime DEFAULT NULL, `date2` datetime DEFAULT NULL, `timestamp1` datetime DEFAULT NULL, `created_at` datetime NOT NULL, `updated_at` datetime NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB }} **config.active_record.default_timezone / config.time_zoneどちらともデフォルト(=UTC)の場合 [#sb9778b9] -保存時にUTCに変換される。 #pre{{ irb(main):002:0> item = DemoItem.new => #<DemoItem id: nil, date1: nil, date2: nil, timestamp1: nil, created_at: nil, updated_at: nil> irb(main):003:0> item.date1 = Time.now => 2013-08-30 17:43:48 +0900 irb(main):005:0> item.save! (0.2ms) BEGIN SQL (0.4ms) INSERT INTO `demo_items` (`created_at`, `date1`, `date2`, `timestamp1`, `updated_at`) VALUES ('2013-08-30 08:44:03', '2013-08-30 08:43:48', NULL, NULL, '2013-08-30 08:44:03') (0.6ms) COMMIT }} -Time.nowした値も、date1に代入するときにActiveSupport::TimeWithZoneに置き換わっている。 #pre{{ irb(main):006:0> item.created_at => Fri, 30 Aug 2013 08:44:03 UTC +00:00 irb(main):007:0> item.date1 => Fri, 30 Aug 2013 08:43:48 UTC +00:00 }} **config.active_record.default_timezone(デフォルト) / config.time_zone(Tokyo)の場合。 [#ae135ee5] -保存される値はUTCだが、表示はJSTになる(参照先リンクとことなりSQLもJSTで表示された)。 #pre{{ irb(main):004:0> item.save! (0.1ms) BEGIN SQL (0.3ms) INSERT INTO `demo_items` (`created_at`, `date1`, `date2`, `timestamp1`, `updated_at`) VALUES ('2013-08-30 08:57:30', '2013-08-30 08:57:18', NULL, NULL, '2013-08-30 08:57:30') (0.3ms) COMMIT }} -表示。 #pre{{ irb(main):005:0> item.date1 => Fri, 30 Aug 2013 17:57:18 JST +09:00 irb(main):006:0> item.created_at => Fri, 30 Aug 2013 17:57:30 JST +09:00 }} **config.active_record.default_timezone(:local) / config.time_zone(Tokyo)の場合。 [#n41fa6be] -全部JSTで統一される。 #pre{{ irb(main):001:0> item = DemoItem.new => #<DemoItem id: nil, date1: nil, date2: nil, timestamp1: nil, created_at: nil, updated_at: nil> irb(main):002:0> item.date1 = Time.now => 2013-08-30 18:01:24 +0900 irb(main):003:0> item.save! (0.1ms) BEGIN SQL (0.3ms) INSERT INTO `demo_items` (`created_at`, `date1`, `date2`, `timestamp1`, `updated_at`) VALUES ('2013-08-30 18:01:30', '2013-08-30 18:01:24', NULL, NULL, '2013-08-30 18:01:30') (0.3ms) COMMIT => true irb(main):004:0> item.date1 => Fri, 30 Aug 2013 18:01:24 JST +09:00 irb(main):005:0> item.created_at => Fri, 30 Aug 2013 18:01:30 JST +09:00 }}