2014-04-01 54 views
1

在9.3.3中,如果一個運行:爲什麼Postgres時區在1967/68左右改變?

select EXTRACT(TIMEZONE FROM timestamp with time zone '1911-03-01 00:00 -8:00:00'), EXTRACT(TIMEZONE FROM timestamp with time zone '1911-05-15 00:00 -8:00:00'), EXTRACT(TIMEZONE FROM timestamp with time zone '1917-03-01 00:00 -8:00:00'), EXTRACT(TIMEZONE FROM timestamp with time zone '1917-05-15 00:00 -8:00:00'), EXTRACT(TIMEZONE FROM timestamp with time zone '1967-03-01 00:00 -8:00:00'), EXTRACT(TIMEZONE FROM timestamp with time zone '1967-05-15 00:00 -8:00:00'), EXTRACT(TIMEZONE FROM timestamp with time zone '1968-03-01 00:00 -8:00:00'), EXTRACT(TIMEZONE FROM timestamp with time zone '1968-05-15 00:00 -8:00:00');

人們得到的結果如下:

0;0; 
0;3600; 
0;3600; 
3600;3600 

(第一次是拉斯維加斯的創始一天,未來幾年有一些我曾經調試過這個問題)

似乎1911年左右沒有偏移,這是1911年到1967年夏季期間的偏移,但不是冬季,然後從1968年開始總是有偏移。這似乎有點奇怪。有沒有人知道這裏的偏移是怎麼回事,這是否是預期的行爲,或者我的linux設置中是否有某些東西可以改變?

+0

哪個是您的時區? – leonbloy

+0

我在倫敦,只是打了日光節約(因此我調查時區!)。 –

+0

我不是在問你「真正的」時區,而是關於你在postgresql中配置的時區(影響結果)。運行'show timezone;' – leonbloy

回答

3

時區因各種原因而改變。

夏時制規則改變。

如果國家出於政治原因重新定義時區,有時時區偏移量也會發生變化。

規範時區信息數據庫是the tz or "zoneinfo" database,以前稱爲Olsen數據庫。 The zoneinfo DB is on the IANA site。有各種各樣的programs to dump human readable versions of the DB

如果您希望在掛鐘時間存儲特定時刻而不考慮時區,則可以使用timestamp without time zone

timestamp with time zone對輸入和輸出設置的系統TimeZone敏感,並以UTC時間存儲爲絕對秒。所以它被轉換爲輸入和輸出。如果您需要不同的轉換或覆蓋轉換,則可以使用AT TIME ZONE運算符。

+0

所以我可以這樣說:'在時區'UTC'選擇帶時區'1911-03-01 00:00 -8:00:00'的時間戳;'這確實正確地給了我結果'1911-03- 01 08:00:00'。不過,我也想提取當時與時間戳相關的偏移量。當我嘗試它時,如同在問題中那樣,它給了我0.如何配置zoneinfo以這種方式做到這一點?不是[this](https://github.com/eggert/tz/blob/master/northamerica)在406行應該是-7:52:58?否則,它是否基於我當地時區的倫敦時間? –

+1

@WilliamBecker不,時間戳在輸入時被轉換*。 TZ偏移量不會保留,並且無法保留並稍後提取。如果你想保留TZ抵消,你必須單獨存儲。是的,這是違反直覺的。 –

1

您所在的時區的規則是由法律規定的,並且法律會發生變化。

+0

這些法律是枚舉的地方,所以我可以確定它爲什麼會如此行事? –

+1

@WilliamBecker:這是相當複雜的:http://www.iana.org/time-zones – leonbloy

+0

因此,這裏是一個公共倉庫zoneinfo db以可讀的格式:https://github.com/eggert/tz/blob /主/北美洲。尋找與太平洋時間相關的洛杉磯,並沒有提到1911年和1921年之間爲什麼會發生變化(參見第400行)。 –

1

如果你想存儲拉斯維加斯(本地)時鐘在該城市創建當天標記爲00:00:00的INSTANT,並假設拉斯維加斯正在使用-8小時的偏移量,那麼您應該將1911-03-01 00:00 -8:00:00::timezonetx存儲在timezonetx字段中。然而,請注意,真正存儲的內容只是「普遍時刻」,當你閱讀它時,你不知道它與哪個「拉斯維加斯當地時間」相對應(除非你明白地將它在閱讀之後轉換爲時區)。

+0

我確實想這樣做,但是如果我運行:'選擇EXTRACT(TIMEZONE FROM timestamp with time zone'1911-03-01 00:00 -8:00:00'),帶時區'1911-03- 01 00:00 -8:00:00';'它給了我一個結果:'0;'1911-03-01 08:00:00 + 00「' - 它丟失了時區信息,這就是爲什麼我問這個問題。我如何將這個偏移量信息存儲在'timestamp with time zone'中? –

+1

你不能在PG。時間戳總是被存儲而沒有時區或偏移量(時區或偏移量僅用於將其轉換爲讀取或寫入)。是的,這很混亂,但日期時間管理很複雜。在評論中閱讀我的鏈接答案。 – leonbloy

+0

因此,對於我的情況,我最好總是使用UTC時區'查詢,以便在任何地方都能獲得一個標準化時間,並將偏移量存儲在另一列中以呈現本地時間? –

0

取決於您的時區,真的。 1966年,DST was first implemented nationally in the US在1967年舉行。國家需要通過法律來結束它,這意味着在許多地區,1967年是使用DST的唯一一年。這可能會導致一些非常有趣的故障,其中除1967/68年的日期以外的每個日期都表現正常。

相關問題