PGAdminでPostgreSQL 11データベースにAWS RDSを使用しています。 now()::timestamp
を使用してすべての行の作成日を保存し、タイムゾーンなしで日付と時刻を保存します。問題は、保存された時間が私が望む値ではないことです(UTC+05:30
)。
RDSでパラメーターtimezone
をUTC
として設定すると、保存される時刻はインドの時刻より5:30時間遅れますが、UTC + 05:30を設定すると、11時間遅れて保存されるか、さらに1時間、これはランダムな行でランダムに発生します。他に何も変更していません。このtimezone
パラメータだけです。
私はたくさん検索しましたが、同様の答えは見つかりませんでした。
TIMESTAMP WITHOUT TIME ZONE
の代わりに、データ型TIMESTAMP WITH TIME ZONE
の列を定義します。AT TIME ZONE 'Asia/Kolkata'
を呼び出します。 (しかし、そのゾーン調整はSQLではなくアプリケーションコードに任せた方が良いです。)TIMESTAMP WITHOUT TIME ZONE
タイムゾーンなしで日付と時刻を保存します。
列を定義するときに間違ったデータ型を使用しています。
TIMESTAMP WITHOUT TIME ZONE
データ型は、モーメントを表すことはできません。
このタイプは、意図的にタイムゾーンのコンテキストまたはUTCからのオフセットを欠いています。したがって、来年の1月23日の正午など、日付と時刻があります。しかし、東京の正午、フランスのトゥールーズの正午、米国のトレドオハイオの正午のどれを意味するのかは、数時間おきにまったく異なります。
入力とともに渡されるタイムゾーンまたはオフセット情報は、TIMESTAMP WITHOUT TIME ZONE
タイプの列に到達すると無視されます。
TIMESTAMP WITH TIME ZONE
TIMESTAMP WITH TIME ZONE
タイプは、タイムライン上の特定のポイントである瞬間を追跡できます。
日付と時刻とともに渡されるタイムゾーンまたはオフセット情報は、UTCに調整するために使用されます。その後、ゾーン/オフセットは破棄されます。したがって、元のゾーン/オフセットを気にする場合は、それを明示的に追加の列に格納する必要があります。
TIMESTAMP WITH TIME ZONE
値を取得する場合、値は常にUTC(ゼロ時分秒のオフセット)になります。ただし、デフォルトのタイムゾーンを挿入するアンチ機能または取得した値にオフセットするツール、ミドルウェア、またはドライバーに注意してください。 実際にPostgresが常にデータタイプTIMESTAMP WITH TIME ZONE
のUTC 値に格納するときに、このゾーン/オフセットが格納されているように見せかけます。
PgAdmin は、この残念なアンチ機能を備えたツールの1つです。セッションのデフォルトゾーンを常にUTCに設定して、取得した値が保存されたときにそれを確認することをお勧めします。
UTCでプログラマーとして考え、働く方法を学ぶことをお勧めします。プログラミングにおけるほとんどのビジネスロジックはUTCである必要があります。ユーザーへの提示またはビジネスロジックが要求する場所でのみタイムゾーンに調整します。つまり、ほとんどの場合、SQLおよびデータベース管理ツールではなく、アプリコードでのみタイムゾーンに調整する必要があります。
AT TIME ZONE
関数ただし、SQLを使用してタイムゾーンに調整する場合は、 AT TIME ZONE
関数を使用します。
UTCの5時間半前のオフセット+05:30
について説明しました。 インドでの時間 を意味していると思います。特定のオフセットではなく、常にリアルタイムゾーン名を優先します。政治家は、管轄区域で使用されるオフセットを頻繁に変更します。そのため、オフセットをハードコーディングすると、誤った結果が生じる可能性があります。
Postgresインストールの tzdata ファイルを最新の状態に保ち、 let Postgresがその特定の瞬間の名前付きタイムゾーンに適切なオフセットを決定します。
… AT TIME ZONE 'Asia/Kolkata' …
私がJava=プログラマーのために作成したこのチャートも、SQL標準で定義されているさまざまなデータ型をよりよく理解するために、ここで役立つかもしれません。
これをデフォルト値として使用する必要があると思います。
current_timestamp AT TIME ZONE '-05:30'
次に、PostgreSQLは現在の時点を取得し、その時点でインドに表示されるタイムスタンプにフォーマットします。