在專案中時常會有用到顯示時間的地方,可能格式只有一種,但是會散落在各個檔案裡,又或者是有許多種的格式。
舉例來說,可能是某個前端 erb 檔案需要撈這筆資料被建立的時間 (create_at),但是不想要 rails 預設給的 format 顯示給使用者。
User.first.created_at.strftime("%F %H:%M")
或者是某個 helper 裡面有個判斷來變更顯示的格式。
# app/helpers/user_helper.rb
module UserHelper
def display_last_update_password_at(last_update_password_at)
if last_update_password_at.nil?
I18n.t('user.labels.no_last_changed')
else
"#{I18n.t('user.labels.last_changed_on')} #{resource.last_update_password_at.strftime('%F %H:%M')}"
end
end
end
不過這樣子的做法會導致 strftime
格式會散落在許多檔案裡,可能 a 檔案跟 b 檔案的邏輯不同,但要顯示的格式相同,也不能整理在一起,更不易閱讀。
註: ruby 內建的 strftime 格式顯示方式這邊就不詳細說明
雖然 rails 有提供 to_s 方法來達到這個需求
datetime = DateTime.civil(2007, 12, 4, 0, 0, 0, 0) # => Tue, 04 Dec 2007 00:00:00 +0000
datetime.to_formatted_s(:db) # => "2007-12-04 00:00:00"
datetime.to_s(:db) # => "2007-12-04 00:00:00"
datetime.to_s(:number) # => "20071204000000"
datetime.to_formatted_s(:short) # => "04 Dec 00:00"
datetime.to_formatted_s(:long) # => "December 04, 2007 00:00"
datetime.to_formatted_s(:long_ordinal) # => "December 4th, 2007 00:00"
datetime.to_formatted_s(:rfc822) # => "Tue, 04 Dec 2007 00:00:00 +0000"
datetime.to_formatted_s(:iso8601) # => "2007-12-04T00:00:00+00:00"
如果想要自己的格式來顯示的話,我們可以建立 time_formats.rb
來設定、整理所有有關時間的格式。
config > initializers > time_formats.rb
# config/initializers/time_formats.rb
Time::DATE_FORMATS[:long_zh_tw] = "%Y年%m月%d日%H時%M分"
Time::DATE_FORMATS[:long_no_separator] = "%Y%m%d%H%M%S"
Time::DATE_FORMATS[:hm_on_today] = "%H:%M"
Time::DATE_FORMATS[:md_on_today_zh_tw] = "%m月%d日"
這樣子在所有地方想要用到這種格式的顯示,就可以 to_s 後接自己的 custom_format 了!
# before
User.first.created_at.strftime("%Y%m%d%H%M%S")
# after
User.first.created_at.to_s(:long_no_separator)
註: 新增 config 需要重啟 server 才會吃得到唷~