1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Ruby & Rails + DB のタイムゾーン

1
Last updated at Posted at 2025-10-28

タイムゾーン

Rubyのタイムゾーン

Ruby の 日時/日付/時間(時刻)を扱うクラスは、(Ruby実行環境を動作させている)システムのタイムゾーンを利用します。

Railsのタイムゾーン

Railsでは、(Railsアプリが稼働する)システムのタイムゾーンとは別にRailsアプリ内で利用するタイムゾーンを設定/参照できます。

なので、Railsには、システムのタイムゾーンとRailsアプリ内で利用するタイムゾーン、の2種類のタイムゾーン設定があります。

システムのタイムゾーンではなくRailsアプリ内で利用するタイムゾーンの利用が推奨されています。

Railsでは、config/application.rbにてconfig.time_zoneに値をセットすることで、Railsアプリ内で利用するタイムゾーンを設定できます。

config.time_zoneのデフォルト値はUTCです。

Railsで日時/日付/時間(時刻)を扱う際にはActiveSupportモジュールのTimeWithZoneクラスを利用することが推奨されています。

TimeWithZoneクラスはconfig.time_zone(Railsアプリ内で利用するタイムゾーン)を内部で参照しています。

Railsでは、ActiveSupportモジュールでTimeクラスが拡張されていて、staticメソッドTime.zone.メソッド名でTimeWithZoneクラスのstaticメソッドにアクセスできます。

Railsでは、ActiveSupportモジュールで Timeクラスが拡張されていて、インスタンスメソッドTime#in_time_zoneで、Timeオブジェクト(インスタンス)をTimeWithZoneオブジェクトに変換できます。

また、TimeWithZoneクラスのインスタンスメソッドTimeWithZone#to_tomeで、TimeWithZoneオブジェクト(インスタンス)をTimeオブジェクトに変換できます。

ActiveSupportモジュールでは、Rubyの他(Date etc)の日時/日付/時間(時刻)を扱うクラスも拡張されています。

DBのタイムゾーン

DBでは、(DBが稼働している)システムのタイムゾーンを利用しています。

DBのタイムゾーン=(DBが稼働している)システムのタイムゾーン です。

なので、DBにタイムゾーンは保存されません。

Railsでは、DBのタイムゾーンを(Railsアプリが稼働している)システムのタイムゾーンと合わせるか、UTC(協定世界時)に設定する必要があります(理由については後述しています)。

Railsのタイムゾーン ⇄ DBのタイムゾーン

Railsでは、config/application.rbにてconfig.active_record.default_timezoneに値をセットすることで、DBの読み書き時のDB(が稼働しているシステム)のタイムゾーンについて設定します。

config.active_record.default_timezoneには2つの値のみしかセットできません。

ActiveRecordで読み書きする際に、:UTCと設定していればDBのタイムゾーンをUTCとして読み書きすることになり、:localと設定していれば、DBのタイムゾーンを(Railsが稼働している)システムのタイムゾーンとして読み書きすることになります。

:UTCをセットした場合、DB(が稼働しているシステム)のタイム・ゾーンをUTCにしなくてはなりません。

:localをセットした場合、DB(が稼働しているシステム)のタイム・ゾーンと(Railsが稼働している)システムのタイムゾーンを一致させなくてはなりません。

config.active_record.default_timezoneのデフォルト値はUTCです。

ActiveRecordが、Railsのタイムゾーン ⇄ DBのタイムゾーンでの(タイムゾーンに合わせた)日時/日付/時間(時刻)の変換を(自動的に)行ってくれます。

システムのタイムゾーン

Railsが稼働しているシステムのタイムゾーン。

RailsアプリをOS直で稼働させている場合、
システムのタイムゾーン=OSのタイムゾーン、
OS上のDocker etcの仮想化環境のコンテナ上で稼働させている場合、
システムのタイムゾーン=コンテナのタイムゾーン、となります。

コンテナのタイムゾーンはホストOS(仮想化環境を動作させているOS)のタイムゾーンとは別に管理されています。

コンテナ定義で、タイムゾーンを設定しなければ、そのコンテナのタイムゾーンはデフォルトのUTCになります。(コンテナのタイムゾーン=コンテナに組み込まれているOSのタイムゾーン。)

Dockerの場合、DockerHubで配布されているコンテナ・イメージのタイムゾーンはUTC(デフォルト)であること多いです。

コンテナ・イメージのタイムゾーンの変更(方法)については別途調べてください。

バックエンド(サーバーサイド)のタイムゾーン

Railsアプリはバックエンドで動作するアプリなので、Railsアプリでは 、バックエンドのタイムゾーン=Railsアプリのタイムゾーン です。

フロントエンド(クライアントサイド)のタイムゾーン

フロントエンドには、ブラウザ、モバイル/デスクトップ アプリ、があります。

フロントエンドのタイムゾーンは、フロントエンドが動作しているシステムのタイムゾーンです。

フロントエンドでは、フロントエンドが動作しているシステム=OSです(例外はあるかもしれません)。

ブラウザのタイムゾーンは、Java Script を用いて取得できます。

フロントエンドのタイムゾーン⇄バックエンドのタイムゾーン

フロントエンドとバックエンドで連携していて、
フロントエンドとバックエンドでタイムゾーンが異なる(可能性がある/マルチ・タイムゾーン含む)場合、フロントエンド・バックエンド間で、タイムゾーンに合わせた日時/日付/時間(時刻)の変換を行う必要があります。

この変換は、フロントエンドで行う方法とバックエンドで行う方法があります。

フロントエンドで行う場合、バックエンドから取得する際+バックエンドに渡す際に日時/日付/時間(時刻)の変換を行うことになります。

フロントエンドのタイムゾーン⇄バックエンドのタイムゾーン⇄DBのタイムゾーン

バックエンドで行う場合、フロントエンドのタイムゾーンをバックエンドに渡して、バックエンドで、フロントエンドに送る際+フロントエンドから取得する際に日時/日付/時間(時刻)の変換を行うことになります。

Railsでは、フロントエンドから取得したタイムゾーンをTime.zoneにセットすることで、データベースに送る際+データベースから取得する際に
ダイレクトに、データベース・フロントエンド間の日時/日付/時間(時刻)の変換を行えます。

フロントエンドのタイムゾーン=バックエンドのタイムゾーン⇄DBのタイムゾーン

Time.zoneで取得できるタイムゾーンのデフォルト値は、config.time_zoneでの設定値です。

フロントエンドのタイムゾーンをバックエンドに渡す方法には、2種類あります。

一つめはCookieを利用する方法です。

フロントエンドでCookieに取得したタイムゾーンをセットし、バックエンドではCookieから取得します。

二つめは、HTTP通信を利用する方法です。

フロントエンドでバックエンドへのリクエスト時にHTTPヘッダーにタイムゾーンをセットし、バックエンドではフロントエンドからのリクエストのHTTPヘッダーから取得します。

旧来のWEBアプリでは、フロントエンド→バックエンド間でのHTTPヘッダーを介したタイムゾーンの伝達はできないので、Cookieを介してタイムゾーンの伝達を行うことになります。

バックエンドで、フロントエンドとの通信とは関係のない、バッチ処理etcを行っている場合、フロントエンドからのタイムゾーンの取得は行えないので、予めフロントエンド+バックエンドで、ユーザー毎?にタイムゾーンの情報を永続化しておき、それをバッチ処理etcで利用することが必要になります。

Cookieでの実装例

HTTP通信での実装例

フロントエンド

バックエンド

Railsのタイムゾーンについての良記事

上記を読んでから、下記を読むと、理解しやすいはずです。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?