Edited at

【初心者向け・動画付き】Railsで日時をフォーマットするときはstrftimeよりも、lメソッドを使おう


はじめに:日時の表示に関してよくある問題

何も考えずにViewにcreated_atのような日付を出力すると、「あれっ?」と思うような表示になることがあります。


app/views/users/index.html.erb

<% @users.each do |user| %>

<tr>
<td><%= user.name %></td>
<!-- 作成日時を表示する -->
<td><%= user.created_at %></td>
<td><%= link_to 'Show', user %></td>
<td><%= link_to 'Edit', edit_user_path(user) %></td>
<td><%= link_to 'Destroy', user, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>

Screen Shot 2019-07-30 at 20.47.50.png

具体的には以下の2つのポイントが「あれっ?」と思う点だと思います。


  • 日本時間(JST)ではなく、世界標準時(UTC)で表示されてしまう

  • "Tue, 30 Jul 2019 00:12:19 +0000"のようなフォーマットは日本人にとって馴染みがない

この記事ではこの問題を解決する方法を紹介します。


タイムゾーンを日本時間に変更する

最初にタイムゾーンを日本時間にしましょう。

config/application.rbに以下の設定を追加し、サーバーを再起動してください。


config/application.rb

module TimeFormatSandbox

class Application < Rails::Application
# ...

# タイムゾーンを日本時間に設定
config.time_zone = 'Asia/Tokyo'
end
end


これで画面に表示された日時が日本時間になります。

Screen Shot 2019-07-30 at 20.52.31.png


日本人が読みやすい日時フォーマットにする

続いて、日時の表示形式を日本人が読みやすいフォーマットに変更しましょう。


:warning: strftimeでも変更できるが、あまりオススメできない

ネットを検索すると以下のようにstrftimeメソッドを使って検索する方法がよく出てきます。

<%= user.created_at.strftime('%Y/%m/%d %H:%M:%S') %>

もちろんこれでも目的は達成できるのですが、他にも日時を表示するViewがあると、'%Y/%m/%d %H:%M:%S'のような書式文字列を繰り返し書かないといけないため、コードがDRYになりません。

DRYでないコードは変更に弱いコードになります。

変更に弱いコードは良くないコードです。


✅ lメソッドでDRYに書式を指定する(オススメ)

Railsにはlメソッドという便利なメソッドがあるので、これを活用しましょう。

以下はlメソッドの使用例です。

<!-- lメソッドを使って書式を指定する -->

<td><%= l user.created_at %></td>

ただし、lメソッドを使うだけでは何も変化がありません。

Screen Shot 2019-07-30 at 20.52.31.png

lメソッドを活用するには、もう少し作業が必要です。

次に行うのはロケールの設定です。

今回は日本人が読みやすい書式にするのが目的なので、アプリケーションのロケールを:jaに設定します。

config/application.rbに以下の設定を追加してください。


config/application.rb

module TimeFormatSandbox

class Application < Rails::Application
# ...

# デフォルトのロケールを日本(ja)に設定
config.i18n.default_locale = :ja
end
end


続いて、config/locales/ja.ymlというファイルを作成し、以下のような設定を記述します。


config/locales/ja.yml

ja:

time:
formats:
default: "%Y/%m/%d %H:%M:%S"

上の設定は日時(time)のデフォルトの書式を%Y/%m/%d %H:%M:%Sにするための設定です。

これでサーバーを再起動すると、日本人向けの書式で日時が表示されます。

Screen Shot 2019-07-30 at 21.33.47.png

strftimeメソッドとは異なり、l foo.created_atのような記述でどのViewでも同じ書式が得られるため、コードもDRYになります。


応用: 複数の書式を使い分ける

lメソッド、便利なんだけど、この画面だけは"07/30 09:12"みたいに短く表示したいんだよな〜 :thinking: 」というそこのあなた!

大丈夫です。formatオプションを付けると、書式を切り替えることができます。

<!-- formatオプションを指定する -->

<td><%= l user.created_at, format: :short %></td>

上の例では:shortを指定したので、ja.ymlに対応する書式を設定します。


ya.yml

ja:

time:
formats:
default: "%Y/%m/%d %H:%M:%S"
short: "%m/%d %H:%M"

ご覧のとおり、書式を切り替えることができました。

Screen Shot 2019-08-02 at 7.13.03.png


Tips: i18n_generatorsでja.ymlを自動生成する

上で作成したconfig/locales/ja.ymlは、i18n_generators gemを使って自動生成すると便利です。

このgemの使い方は以下のとおりです。

まず、Gemfileにi18n_generatorsを追加し、bundle installを実行します。


Gemfile

group :development do

# ...

gem 'i18n_generators'
end


次にターミナルから以下のコマンドを実行します。

rails g i18n_locale ja

config/locales/ja.ymlが生成されるので、このファイルを開いてja.time.formats.defaultの書式文字列を編集します。

デフォルトの書式文字列は "%Y年%m月%d日(%a) %H時%M分%S秒 %z" になっているので、これを要件に合わせて変更してください。

なお、i18n_generatorsが生成したja.ymlには他にも日本語ロケール向けの設定がたくさん定義されています。

i18n_generatorsに関する詳しい情報はREADMEを参照してください。

https://github.com/amatsuda/i18n_generators


Tips: View以外ではI18n.lを使う

Viewではlと書くだけでOKですが、lメソッドがヘルパーメソッドとして提供されていない場所(Modelなど)では、lだけではNoMethodErrorになります。

その場合は、lの代わりにI18n.lと書けば、日時をフォーマットすることができます。

ちなみにllocalizeのエイリアスメソッドなので、localizeと書いても構いません。

以下の記述はどれも同じ結果になります。

= l user.created_at

= I18n.l user.created_at
= localize user.created_at
= I18n.localize user.created_at


追記:Time::DATE_FORMATS[:default]を変更するのもオススメしない

日時のフォーマットを変更する方法としてもうひとつ、Time::DATE_FORMATS[:default]の設定を変えるという方法もあるようです。


config/initializers/time_formats.rb

Time::DATE_FORMATS[:default] = '%Y/%m/%d %H:%M:%S'


こうすると、lメソッドもstrftimeも使わずに書式を統一することができます。

<!-- 何もしなくても書式が'%Y/%m/%d %H:%M:%S'になる -->

<td><%= user.created_at %></td>

これだけ見ると「すごく便利じゃん!」と思うかもしれません。

ですが、アプリケーション全体のデフォルト設定が変わってしまうため、予期しない問題を引き起こすかもしれません。

実際に問題が発生する事例は以下の記事で紹介されています。

RailsのTime::DATE_FORMATS[:default]は変更しないほうがいい - Qiita

ですので、この方法もあまりオススメできません。


動画はこちら

この記事の内容はYouTube動画としてアップしています。

動画を見たい方は以下のリンクから視聴してください。

https://youtu.be/QUnWDvPONAo


参考文献