LoginSignup
0
0

More than 3 years have passed since last update.

[Rails] strftime vs I18n.localize vs to_s(:Time::DATE_FORMATS) どれを使うべきか?

Last updated at Posted at 2021-03-06

結論

I18n.localizeがオススメ

理由

  • 日時表示専用のメソッドだから(= スコープが小さく、オーバーライドしやすいから )

strftimeがダメな理由

  • undefined method strftime for nil:NilClassエラーを回避するために無闇に&をつけるから
  • 日時を表示するのに長ったらしいメソッド名・時刻フォーマットを書くのはめんどくさいから

to_s(:Time::DATE_FORMATS)がダメな理由

  • スコープが広く、オーバーライドできない(すべきでない)から

to_snilを渡すと空文字を返す。

$ nil.to_s
=> ""

しかし、to_s(:Time::DATE_FORMATS)にするとArgumentErrorが発生する。

$ Time::DATE_FORMATS[:sample_format] = "%Y年%m月%d日"
=> "%Y年%m月%d日"

$ Time.now.to_s(:sample_format)
=> "2021年01月01日"

$ nil.to_s(:sample_format)
=> ArgumentError: wrong number of arguments (given 1, expected 0)

to_sで時刻フォーマットを指定できるが、nilを渡してもエラーを吐かないto_sの使いやすさがなくなった。
to_s&を毎回書くのは美しくないし、strftimeとやってる事が変わらなくなる。

I18n.localizenilが渡るとエラーが起きる。

config/locales/ja.yml
ja:
  time:
    formats:
      default: "%Y年%m月%d日"
$ I18n.l(Time.now)
=> "2021年01月01日"

$ I18n.l(nil)
=> I18n::ArgumentError: Object must be a Date, DateTime or Time object. nil given.

なので

  1. 諦めて永遠と&を使い続ける(論外)
  2. begin rescueでエラーをキャッチする(論外)
  3. オーバーライドしてnilをパスさせるか

どれかの対応が必要になる。
1は論外。美しくない。
2も論外。毎回begin resucueするのはダルい。美しくない。
必然的に3で対応することになるが、to_sは影響範囲が広く懸念が大きい。
なので、日時表示専用メソッドでスコープが小さく影響範囲が狭いI18n.localizeをオーバーライドするのがオススメ
オーバーライドの方法は、以下を参考にしてほしい。
http://hamasyou.com/blog/2014/02/19/rails-i18n-localize/

この記事を書こうと思った経緯と所感

I18n.localizeが日時表示用のメソッドならば、これ使えばいいんじゃね?」

って思ってました。
しかし、デフォルトではnilをパスできないと知って、他のメソッドを調べました。
その際に、to_sメソッドの引数に時刻フォーマットを設定すれば日時を表示できると知りました(to_sメソッド万能スギィィ!!!
しかし、

to_sでフォーマットを指定できるが、nilを渡してもエラーを吐かないto_sの使いやすさがなくなりました。。。

&でエラー回避できますが、strftimeとやってることは変わらないし、コードが美しくないと思いました。
このように、コードの保守性とメソッドスコープの観点からI18n.localizeをオーバーライドするのがベストだと考えました。

参考文献

0
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
0
0