Heroku としては DB のタイムゾーンは UTC としておくことを推奨しています。例えばユーザ環境が JST となる場合、保存時には -9時間 (UTC変換) し、表示時に +9時間 (JST変換) する形となります。
こちらは Heroku Postgres の例となりますが、 How to change the Timezone setting for Heroku Postgres? でもデータベースのタイムゾーンは UTC に設定し、アプリケーションレベルでの変換を推奨しています。
以下、推奨される方法ではありませんが、元記事を残しておきます。
DB を直接参照した時に created_at が UTC になっていることに気がつくこと、よくありますよね。
TL; DR
- heroku 使うときは
heroku config:add TZ=Asia/Tokyo
し忘れがちなので気をつけろ - リカバる時は
heroku run bash
してから Rails Console 立ち上げろ
まず確認するポイント
time_zone, default_timezone
# config/application.rb
config.time_zone = "Tokyo"
config.active_record.default_timezone = :local
こちらは問題なし。
heroku config
$ heroku config
=== app-name Config Vars
JAWSDB_URL: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
LANG: en_US.UTF-8
RACK_ENV: production
RAILS_ENV: production
RAILS_LOG_TO_STDOUT: enabled
RAILS_MASTER_KEY: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
RAILS_SERVE_STATIC_FILES: enabled
SECRET_KEY_BASE: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
TZ 設定忘れてますね...
リカバリ作業
1. heroku のタイムゾーンを Tokyo にする
$ heroku config:add TZ=Asia/Tokyo
2. ついでに LANG も変更する
$ heroku config:add LANG=ja_JP.UTF-8
3. Heroku に SSH
$ heroku run bash
Running bash on ⬢ app-name... up, run.6391 (Free)
4. Rails Console の立ち上げ
$ rails c -e production
Loading production environment (Rails 5.1.4)
時間修正
irb(main):001:0> tasks = Task.where("created_at < ?" , "2017-12-19 21:10:00") # ※1
=> #<ActiveRecord::Relation [#<Task id: 1, name: "洗濯", created_at: "2017-12-16 05:06:45", updated_at: "2017-12-16 05:06:45">, #<Task id: 2, name: "風呂掃除", created_at: "2017-12-16 05:06:58", updated_at: "2017-12-16 05:06:58">, #<Task id: 3, name: "トイレ掃除", created_at: "2017-12-16 05:07:04", updated_at: "2017-12-16 05:07:04">, #<Task id: 4, name: "電子レンジ掃除", created_at: "2017-12-16 05:07:16", updated_at: "2017-12-16 05:07:16">]>
irb(main):002:0> tasks.update_all("created_at = created_at + interval 9 hour")
=> 4
irb(main):003:0> tasks.update_all("updated_at = updated_at + interval 9 hour")
=> 4
irb(main):004:0> tasks.map{|t| Rails.logger.info "id: #{t.id}, created_at: #{t.created_at}, updated_at: #{t.updated_at}"}
I, [2017-12-19T21:17:52.254054 #8] INFO -- : id: 1, created_at: 2017-12-16 23:06:45 +0900, updated_at: 2017-12-16 3:06:45 +0900
I, [2017-12-19T21:17:52.254558 #8] INFO -- : id: 2, created_at: 2017-12-16 23:06:58 +0900, updated_at: 2017-12-16 3:06:58 +0900
I, [2017-12-19T21:17:52.254790 #8] INFO -- : id: 3, created_at: 2017-12-16 23:07:04 +0900, updated_at: 2017-12-16 3:07:04 +0900
I, [2017-12-19T21:17:52.254968 #8] INFO -- : id: 4, created_at: 2017-12-16 23:07:16 +0900, updated_at: 2017-12-16 3:07:16 +0900
=> [true, true, true, true]
※1 「1. heroku のタイムゾーンを Tokyo にする」 の実施時間より前の日時を where
句に指定すること
蛇足
TZ
設定し忘れがちなので、 Terraform 書いた
tetsuya/kochiku-heroku