Karakuri.com

ベンチャー企業で働くソフトウェアエンジニアの技術録

Ruby on RailsとPostgreSQLとHerokuのタイムゾーンの設定と関係で混乱したので調べました

スポンサーリンク

会社のWebサービスがRailsでPostgreSQLを使っているのですが、DBで保存されているタイムスタンプのタイムゾーンがよく分からず小一時間調べて複雑だったのでメモ。

それぞれのタイムゾーン設定状況

Ruby on Railsのタイムゾーン設定

config.active_record.default_timezone = :local
config.time_zone = 'Tokyo'

application.rbのconfig.time_zoneはRuby on Railsのタイムゾーンで理解しやすいのですが、config.active_record.default_timezoneの認識を間違っていてハマってしまいました。config.active_record.default_timezoneはActiveRecordがDBの読み書きに使用するタイムゾーンと理解すれば良いようです。このため、DBにタイムゾーンを設定していてもRails側はconfig.active_record.default_timezoneの設定したタイムゾーンで時間を取り扱います。そしてここを:localにしたとき、それはDBの設定を使うという意味ではなく、サーバーの設定を使うという意味です。Herokuを使っているならHeroku、DockerならDockerのタイムゾーンになるわけですね。

PostgreSQLのタイムゾーン設定

show timezone;

Postgreにログインして上記のコマンドで設定しているタイムゾーンを確認できます。UTCでした。

Herokuのタイムゾーン設定

$ heroku run bash
$ date

Herokuにログインしてbashでタイムゾーンを確認できます。JSTでした。

ActiveRecordのタイムゾーンは何になるのか

というわけで、まとめると設定は下記の通りになります。

  • Ruby on Rails JST
  • ActiveRecord Herokuに準拠
  • PostgreSQL UTC
  • Heroku JST

つまり、WebサービスはJSTで動いているということになります。ActiveRecordはJSTで時間を読み書きし、Ruby on RailsもJSTで取り扱います。しかしPostgreSQLは時刻をUTCで保存していると思っています。これは気持ち悪いですね…。なんでこんな設定にしてしまっているんだろう…。