3

これは本当に簡単なはずですが、私はそれで恥ずかしいほどのトラブルを抱えています.

PostgreSQL 9.1 ではDATE、DB に として格納されているフィールドをTIMESTAMPTZ、その日付の午前 0 時 UTC を表すものとして解釈する必要があります。誰かがやって来て、何が起こっているのかを見て、理解できるように、きれいで読みやすい方法でそれを行いたいと思います。

これまでに見つけた唯一の方法は、どちらも非常に醜いものです。それを に変換し、それを UTC であるかのように解釈して、そこからTIMESTAMP WITHOUT TIME ZONEを作成します。TIMESTAMP WITH TIME ZONE

SELECT CAST(DATE '2012-01-01' AS TIMESTAMP WITHOUT TIME ZONE) AT TIME ZONE 'utc'

他の方法はもっと悪いです:

('2012-01-01'::date)::timestamptz - (current_timestamp AT TIME ZONE 'UTC' - current_timestamp)

日付を現地時間の午前 0 時のタイムスタンプに変換してから、タイム ゾーン オフセットを減算します。そのオフセットをネイティブに間隔として取得する方法が見つからなかったので (クレイジーに思えます) current_timestamp、現地時間とcurrent_timestampUTC を比較して取得しました。

私が解決できる唯一の他の方法はextract、日付の部品を入手して、それらから新しい部品を組み立てるtimestamptzことでした。私はそれを見せることさえしません、それはあまりにも醜いです.

どちらのアプローチも、あらゆる種類の奇妙で間違っていると感じます。その日の真夜中の UTC のDATEaから a に読みやすく、簡単に理解できる方法で変換するための正気な方法 (標準またはいいえ) はありますか?timestamptz

私は次のようなものを探しています(架空の、機能しません)

'2012-01-01'::date AS TIMESTAMPTZ IN TIME ZONE '00:00';

また

to_timestamp('2012-01-01'::date, '00:00'::time, 'UTC');

私が見逃している愚かなことを指摘してください。

extract(epoch from $1)表示時だけでなく、変換された日付がどこにあるのか、日付が内部的に本当に正しいことを確認するためにテストしていることに注意してください$1

4

2 に答える 2

4

あなたの最初のアプローチは正しいです。そして、それはそれほど醜いものではありませんよね?単純化された Postgres 構文では:

SELECT '2012-1-1'::date::timestamp AT TIME ZONE 'UTC';

変数または列に適用すると、さらにエレガントに見えます。

SELECT mydate::timestamp AT TIME ZONE 'UTC';

日付を手動で入力する場合は、次のようにショートカットできます。

SELECT '2012-1-1 0:0'::timestamp AT TIME ZONE 'UTC'

結果は常に、クライアントのローカル タイムゾーンに従って (つまり、オフセットに応じて)表示されますが、には影響しません。

于 2012-08-23T14:41:57.913 に答える
2

注: PSQL についてはよくわかりませんが、日付/時刻の問題についてはある程度の経験があります。

あなたの最初の方法は私にとって正しいと感じます。「ローカル日付」から「ローカル日付/時間」、「特定のタイムゾーンの日付/時間」に効果的に移行しています。これらはすべて合理的な手順であり、通常の日付/時刻 API で見られると思われる手順です。

このアプローチは、私が知る限り、システムのデフォルトのタイムゾーンを導入することはありません。これは完全に良いことです. キャストが賢明なものであると仮定して、一度に 1 つの論理ステップを実行します。

UTC には DST 移行がないため、ローカルの日付/時刻があいまいになったり、ターゲット タイム ゾーンに含まれていなかったりすることを心配する必要はありません。

基本的に見た目は問題ありません。それが機能し、必要に応じて機能する場合、私はそれを使い続けます.

于 2012-08-23T13:23:10.940 に答える