web-dev-qa-db-ja.com

なぜタイムゾーンは0001年にPostgresでこんなに狂ったUTCからのオフセットを持っているのですか?

Postgres 9.5では、0001年(ゼロなし0000)を試してみたところ、以下の結果に驚かされました。

-07:52:58?のオフセット

いくつかのサンプルコード。 TIMESTAMP WITH TIME ZONETIMESTAMP WITHOUT TIME ZONEの混合使用に注意してください。注意して読んでください。

SET TIME ZONE 'America/Los_Angeles' ;

SELECT (TIMESTAMP WITH TIME ZONE '2015-01-01 00:00:00.0', 
        TIMESTAMP WITH TIME ZONE '0001-01-01 00:00:00.0Z', 
        TIMESTAMP WITHOUT TIME ZONE '0001-01-01 00:00:00.0Z') ;

("2015-01-01 00:00:00-08","0001-12-31 16:07:02-07:52:58 BC","0001-01-01 00:00:00")

2番目の値0001-12-31 16:07:02-07:52:58 BCに驚いています。 America/Los_AngelesはUTCから8時間遅れて-08:00のオフセットがあるため、8時間前に戻る必要があることを理解しています。 しかし、-08:00の代わりに、オフセットは-07:52:58です。なぜですか?

UTCで問題なし

UTCでデータを入力する場合、そのような問題はありません。

SET TIME ZONE 'UTC' ;

SELECT (TIMESTAMP WITH TIME ZONE '2015-01-01 00:00:00.0',  
        TIMESTAMP WITH TIME ZONE '0001-01-01 00:00:00.0Z', 
        TIMESTAMP WITHOUT TIME ZONE '0001-01-01 00:00:00.0Z');

("2015-01-01 00:00:00+00","0001-01-01 00:00:00+00","0001-01-01 00:00:00")

ノーイヤーゼロ

ちなみに日付部分は正しいようです。 「BC」と「AD」の時代の間のピボットポイントである0000の年はないようです。 0001年の最初の瞬間を取り、1時間を引くと、0001 BCという年が得られます。つまり、ゼロ年はありません。

SET TIME ZONE 'UTC' ;

INSERT INTO moment_  -- TIMESTAMP WITH TIME ZONE.
VALUES ( TIMESTAMP '0001-01-01 00:00:00.0Z' - INTERVAL '1 hour' ) ;

SET TIME ZONE 'UTC' ;

TABLE moment_ ;

結果は年0001 BCなので、0001から0001 BCにジャンプします。ゼロ年なし0000

"0001-12-31 23:00:00+00 BC"
16
Basil Bourque

1883年11月18日の12:00(新しい時刻)に、アメリカの鉄道では標準時間が採用されました。

つまり、それ以前は、ロサンゼルスは平均太陽時間に基づいた実際の現地時間を使用していました。その後、グリニッジ標準時からの時間の積分オフセットであるローカルタイムゾーンに移動しましたが、以前の時間とは少し異なっていました。

もっと知りたい?

  • IANA:タイムゾーン からtzdataタイムゾーンデータベースをダウンロードします。

  • 内部には、(多くの)タイムゾーンの定義があり、時間の経過に伴って多くの変化があり、加えられた変更がいつどこで行われたかを詳しく説明する多くのコメントがあります。それは面白い読書です!

  • ウィキペディアには、1883年11月18日の変更に関する ウィキペディア:タイムゾーン ページにも興味深い事実があります。

鉄道時間
...
19世紀半ばのアメリカの鉄道の計時はやや混乱していた。各鉄道は、通常、本社または最も重要な終着点の現地時間に基づいて、独自の標準時間を使用し、鉄道の列車の時刻表は、独自の時間を使用して公開されました。いくつかの鉄道が運行するジャンクションには、各鉄道の時計があり、それぞれが異なる時刻を示していました。
...ダウドのシステムはアメリカの鉄道では決して受け入れられませんでした。代わりに、米国とカナダの鉄道は、旅行者の公式鉄道ガイドの編集者であるウィリアムF.アレンが提案したバージョンを実装しました。そのタイムゾーンの境界は、多くの場合主要都市の鉄道駅を通りました。たとえば、東部と中央部のタイムゾーンの境界は、デトロイト、バッファロー、ピッツバーグ、アトランタ、およびチャールストンを通っていました。 1883年11月18日、また、「2つの昼の日」、各タイムゾーン内で標準時間の正午に達したときに各鉄道駅の時計がリセットされたとき。ゾーンは、コロニアル、イースタン、セントラル、マウンテン、パシフィックと命名されました。 ...

これはPostgresqlに固有のものではないことにも注意してください。これは、tzdataデータベースを使用するすべてのソフトウェアまたはオペレーティングシステムに有効です(もちろん、多くは1970年以降または1901年以降の日付に限定されるため、1883年は手の届かないところにありますが、他にも多くの調整があります。別の時間)。

22
jcaron