こんにちは、ジョンです!
今回は、Railsでの現在日時を取得するメソッドについてまとめてみました。
簡単に見える現在時刻の取得ですが、実は結構大きな違いを持っていて、
それを知らないと、思わぬバグを呼び込むことになりかねません。
この記事で、少しでもRailsに興味を持ってくれる方が増えてくれると嬉しい限りです。
※12月14日、一部間違った記載がありましたので、記事を修正しました。
現在時刻を取得する
現在時刻を取得するクラスは、大きく分けて2つあります。
Date: 時間情報がなく、日付情報だけを取得するクラス
Time: 日付+時間情報を取得できるクラス
それぞれで、現在の時間を取得する方法について記載していきます。
今日の日付を取得する
> Date.current
=> Sun, 13 Dec 2021
> Date.today
=> Sat, 13 Dec 2021
現在の時刻を取得する
> Time.current
=> Sun, 13 Dec 2021 21:00:00 JST +09:00
> Time.now
=> Sun, 13 Dec 2021 21:00:00 JST +09:00
非推奨なクラス
> DateTime.current
=> Sun, 13 Dec 2021 21:00:00 JST +09:00
DateTimeとは、Dateクラスに時刻情報も付与されたDateのサブクラスです。
しかしながら、現在DateTimeクラスは deprecated(非推奨) とされており、
TimeWithZoneクラスを使うことを推奨されているため、この記事では詳細を割愛します。
TimeWithZoneクラス
更に、Railsでは、TimeWithZoneクラスを使うことを推奨されています。
> Time.zone.now
=> Sun, 13 Dec 2021 21:00:00 JST +09:00
ただし、このTimeWithZoneクラスは、Railsアプリケーション内でのタイムゾーンの設定が重要になります。
詳しくは次の項目で見ていきましょう。
current と now って何が違うの?
上の例を見ていただくと分かる通り、基本的に、どちらも現在の日時を取得するメソッドです。
しかし、この2つには大きな違いがあり、違いを理解していないと重大なバグを生むことがあります。
それは、参照しているタイムゾーン設定が異なる、という違いです。
まず、Date.todayやTime.nowはどちらも、Railsではなく、rubyのメソッドです。
そのため、today, nowについては、アプリが動いているサーバーの環境変数、
ENV['TZ']
に依存します。
※ちなみに環境変数が設定されていない場合、OSのタイムゾーンにより決まります。
一方で、currentについては、Railsのメソッドとなっていて、
Railsのconfigファイルに書かれたタイムゾーンを参照しています。
config.time_zone = 'Tokyo'
ただし、Rails側でこの設定がなかった場合、Railsアプリが乗っているサーバーの環境変数を参照します。
Railsのconfig/application.rbにしっかりとタイムゾーンの設定を明記しないと、

ステージング環境に上がった瞬間、9時間前の時間になってしまった!

などと言った問題が発生する危険性を持っています。
つまり、全ての環境で正しく「現在の時間」を取得するためには、
- config/application.rb にしっかり timezone を記載する
- Time.now ではなく、Time.zone.now を使う
を徹底するようにしましょう。
まとめ
さて、今回は現在日時の取得についてまとめてみました。
今回の記事の要点をまとめると、以下のとおりです。
- 日付だけ取りたければ Date, 時間もほしければ Timeクラス
- .today や .now ではなく、 Time.zone.nowを使おう
- config/application.rb にて、しっかり timezone の設定をしよう
次回、日時関連の繋がりで、Railsならではの便利なメソッドを紹介したいと思います!
この記事が、どなたかのお役に立てれば幸いです。
参考文献
Railsドキュメント – 設定ファイル(config)
https://railsdoc.com/config#config_time_zone