在 postgres 中明確保留時區
我一直在對“查看”時間的不同方式以及如何在 Postgres 中正確映射時間進行相當多的研究,但我仍然不確定實際使用什麼。有幾篇文章建議或者更確切地說是說服您將日期儲存
timestamp with time zone
為timestamp
. 我特別在夏令時苦苦掙扎。我的案例是一個簡單的面向最終使用者的應用程序,只有“歐洲/柏林”時區的人才能訪問。使用者編寫的文章與時間戳一起儲存以進行創建和更新。
假設使用者在
2020-01-01T10:00:00+01
. 如果使用者現在在同一天閱讀該文章,它應該顯示posted on 1st of January at 10 am
. 如果同一篇文章在 7 月在柏林被點擊,它仍然應該說posted on 1st of January at 10 am
不管 DST。我現在的直覺是將時間儲存為 a
timestamp without time zone
,否則 Postgres 會將時間轉換為 UTC 並以這種方式儲存。後來我將無法參考發布該文章的實際時區。在這種情況下,它會顯示posted on 1st of January at 11 am
(由於柏林現在提前兩個小時),如果他們要檢查他們最初的時間,這可能會使作者感到困惑發表了文章。我的想法是否正確,我是否找到了不使用的極端案例之一,
timestamp with time zone
或者我在這裡遺漏了一些重要的東西?
我的案例是一個簡單的面向最終使用者的應用程序,只有“歐洲/柏林”時區的人才能訪問。
$$ … $$ 我現在的直覺是將時間儲存為
timestamp without time zone
因為$$ … $$ 後來我將無法參考發布該文章的實際時區。
這表明源於不幸的數據類型名稱的****誤解:
timestamp without time zone
(=timestamp
)timestamp with time zone
( =timestamptz
)兩種數據類型都不儲存任何時區資訊。
timestamptz
只需添加輸入和輸出邏輯以考慮目前會話的timezone
設置,並相應地從 / 到 UTC 時間進行投影。如果這讓您感到困惑,請不要太尷尬,它發生在我們中最好的人身上:
在您的特定情況下
如果您的陳述可靠:
只有“歐洲/柏林”時區的人才能訪問。
…那麼您不妨只使用
timestamp
. 您知道隨附的時區。並且輸入和輸出之間沒有轉換。您可以通過以下方式timestamptz
即時轉換為:my_column AT TIME ZONE 'Europe/Berlin'
如果您的應用程序應該超出目前範圍,並且您需要切換到
timestamptz
以輕鬆促進來自多個時區的輸入,請轉換為:ALTER TABLE tbl ALTER col TYPE timestamptz USING my_column AT TIME ZONE 'Europe/Berlin'
請務必使用時區名稱“Europe/Berlin”,而不是無法針對 DST 變化進行調整的硬編碼偏移量,也不是time zone abbreviation,它只是硬編碼偏移量的名稱 - 其中另一個很常見的誤解。
或立即使用
timestmaptz
以涵蓋所有可能性。無論哪種方式,要像您要求的那樣保留時區,您需要明確儲存它們(在附加列中),因為否則不會保存 - 您不能再假設“歐洲/柏林”。
有關的: