冒險村09 - Time format config

09 - Time format

在專案中時常會有用到顯示時間的地方,可能格式只有一種,但是會散落在各個檔案裡,又或者是有許多種的格式。

舉例來說,可能是某個前端 erb 檔案需要撈這筆資料被建立的時間 (create_at),但是不想要 rails 預設給的 format 顯示給使用者。

1
User.first.created_at.strftime("%F %H:%M")

或者是某個 helper 裡面有個判斷來變更顯示的格式。

1
2
3
4
5
6
7
8
9
10
# 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 方法來達到這個需求

1
2
3
4
5
6
7
8
9
10
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 來設定、整理所有有關時間的格式。

Setting config > initializers > time_formats.rb

1
2
3
4
5
6
# 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 了!

1
2
3
4
5
# before
User.first.created_at.strftime("%Y%m%d%H%M%S")

# after
User.first.created_at.to_s(:long_no_separator)

註: 新增 config 需要重啟 server 才會吃得到唷~

參考來源