rails をタイムゾーンの設定をしないまま時刻をDBに保存したら UTC の時刻として解釈されてしまった。

irb(main):001:0> user = User.new(last_login_at: "2024/07/01 10:00")
=>
#<User:0x00007fe26547b680
...
irb(main):002:0> user.last_login_at
=> Mon, 01 Jul 2024 10:00:00.000000000 UTC +00:00

タイムゾーンの設定や時刻の取り扱いについて整理する。

Time と ActiveSupport::TimeWithZone の違い

  • Time クラス
    • ruby の組み込みクラス
    • タイムゾーンは OS または環境変数 TZ を参照する
    • Time.nowTime.parse などのように使う。
irb(main):01:0> time = Time.now
=> 2024-06-30 20:24:14.077687386 +0900
irb(main):02:0> time.class
=> Time
  • ActiveSupport::TimeWithZone
    • active_support のクラス
    • タイムゾーンは config.time_zone を参照する
    • 設定しているもの以外のタイムゾーンも扱える
    • Time.zone.nowTime.zone.parse などのように使う。
irb(main):01:0> time = Time.zone.now
=> Thu, 30 Jun 2024 11:25:14.080435073 UTC +00:00
irb(main):02:0> time.class
=> ActiveSupport::TimeZone

config.active_record.default_timezone について

  • データベースに格納する時刻をどのタイムゾーンの時刻として扱うかを設定
  • :utc か :local を設定できる
  • デフォルトは :utc

設定

アプリケーションで扱うときに変換してくれればよいので格納するデータは UTC 時刻のままとし、rails のタイムゾーンは JST に設定する。

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