Postgresql

在 postgres 中明確保留時區

  • February 14, 2020

我一直在對“查看”時間的不同方式以及如何在 Postgres 中正確映射時間進行相當多的研究,但我仍然不確定實際使用什麼。有幾篇文章建議或者更確切地說是說服您將日期儲存timestamp with time zonetimestamp. 我特別在夏令時苦苦掙扎。

我的案例是一個簡單的面向最終使用者的應用程序,只有“歐洲/柏林”時區的人才能訪問。使用者編寫的文章與時間戳一起儲存以進行創建和更新。

假設使用者在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以涵蓋所有可能性。

無論哪種方式,要像您要求的那樣保留時區,您需要明確儲存它們(在附加列中),因為否則不會保存 - 您不能再假設“歐洲/柏林”。

有關的:

引用自:https://dba.stackexchange.com/questions/259719