2

Rails 要用 Time.zone.now 還是 Time.now

 2 years ago
source link: https://blog.niclin.tw/2019/06/27/rails_time_now_vs_time_zone_now/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Nic Lin's Blog

喜歡在地上滾的工程師

我自己主觀喜歡用 Time.zone.now

  1. 在 Rails best practice 裡有提到
  2. 把時區的設定放在 application layer 而不是機器上
  • Time.now 抓的是機器時間
  • Time.zone.now 抓的是 Rails 下設定的 config.time_zone 時區

如果機器沒設定好,不管是 development / production 又或是多機器的部分,就有可能顯示不一樣。

而時間的格式應該仰賴在 application layer, 這樣更容易保持一致性

可以在本機測試以下範例

  1. config/application.rb 中的時區替換為 config.time_zone = 'Europe/Istanbul'
  2. 啟動 Rails console
  3. 輸入 Time.now / Time.zone.now 查看
# 我已經改為非 asia 時區,但他抓的是我機器上的時區
pry(main)> Time.now
=> 2019-06-26 14:24:08 +0800

# 下面這個應該才是對的
pry(main)> Time.zone.now
=> Wed, 26 Jun 2019 09:24:05 +03 +03:00

但是寫進 database 時都是會轉 UTC,其實你不管用 Time.now / Time.zone.now 其實都可以。

如果你機器上設定的時區和 Rails 裡一樣,那麼這兩個方法其實出來的結果是一致的。

那為什麼還是推薦用 Time.zone.now ?

舉個例子,也許不會發生,但可以想想

如果機器有很多台,可能某一台在當初開的時候沒設定好時區。

那麼在 database 寫入時,不用擔心,不會有事,不管 zone 是什麼,都會寫入當下時間並轉為 UTC,因為 db 不負責記錄 zone。

但是顯示的部分,可能就會有雷。

A 機器被設錯了,是歐洲時區。 B 機器是對的,是亞洲時區。

你有一個頁面是透過 load balance 進來,所以用戶有可能連到 A 也有可能是 B

你有頁面的邏輯是顯示現在的時間 + 30.mintues。

可以想一下 A 和 B 機器分別在頁面上顯示的結果

  • Time.now + 30.mintues
  • Time.zone.now + 30.mintues

定然是不一樣的吧?

所以如果你不想區分,model 寫 Time.now而 View / API output 寫 Time.zone.now

那我認為就統一寫 Time.zone.now 並把 Rails 時區設定好,大家就更方便做事囉。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK