Rails・データベース・OSのTimeZoneの調べ方

必要に迫られタイトルに挙げたもののTimeZoneの調べ方をマスターしてしまったので、ブログに残しておきます。

# RailsのTimeZoneを調べる場合(コンソールからの調査)

# config/application.rbの設定が返る
Rails.application.config.time_zone
=> "Asia/Tokyo"
# データベースのTimeZoneを調べる場合(Railsコンソールからの調査)
# PostgreSQLを使っている前提

ActiveRecord::Base.connection.execute("SHOW timezone").first["timezone"]
=> "Asia/Tokyo"
# OSのTimeZoneを調べる場合
# Linuxサーバー前提

timedatectl | grep "Time zone"
=> Time zone: Japan (JST, +0900)

upsert_all メソッドのオプションにrecord_timestamps: true を渡してバルクインサートすると、なぜか 時刻が18時間ズレるという問題に現在進行形で直面しておりまして、

色々調べたところ、record_timestamps: true だと DBの CURRENT_TIMESTAMP 関数が呼ばれてるようで、

https://github.com/rails/rails/blob/main/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb#L496

ActiveRecord::Base.connection.execute("select current_timestamp;").first
=> {"current_timestamp"=>"2023-08-10T03:47:53.130-09:00"}

見事に18時間ズレている!というところまではわかったのですが、もう upsert_all ではなく activerecord-importのimportメソッドでバルクインサートしようかなと考え始めているところでした。

activerecord-importのimportメソッドであれば、created_atおよびupdated_atの値に、timestamp = default_timezone == :utc ? Time.now.utc : Time.now の返り値を採用しているため、

upsert_allにこだわることもないかなと考え始めていました。同じ問題に遭遇している方はいるのだろうか。