ティボさんの回答は正しいです。私の追加の考えは続きます。
使用するTIMESTAMP WITH TIME ZONE
TIMESTAMP WITHOUT TIME ZONE
Postgres でのデータ型の使用について言及しました。そのタイプは、特定のタイムゾーンに関連付けられていない日時専用です。たとえば、「クリスマスは 2015 年 12 月 25 日の午前 0 時に始まります」は、特定のタイム ゾーンの別の瞬間に変換されます。たとえば、クリスマスはモントリオールよりもパリの方が早く始まります。このデータ型は、ビジネス アプリではほとんど適切ではありません。この Postgres エキスパートの投稿、Always use TIMESTAMP WITH TIME ZONEを参照してください。
Postgres では、もう一方のタイプTIMESTAMP WITH TIME ZONE
は「タイム ゾーンを尊重して」という意味です。着信データの UTC またはタイム ゾーン情報からのオフセットは、UTC に調整するために使用されます。付随するオフセットまたはタイム ゾーン情報は破棄されます。一部のデータベースはこの情報を保存しますが、Postgres は保存しません。
あなたの声明:
データベースは PostgreSQL にあります。データベースは、アジア/テヘランのタイム ゾーンで構成されています。
…意味がありません。データ型TIMESTAMP WITHOUT TIME ZONE
にはタイム ゾーンがなく (UTC と見なすこともできます)、データ型TIMESTAMP WITH TIME ZONE
は常にUTCです。日時値の格納に関しては、そのようなタイム ゾーン構成はありません。
データベース セッションのデフォルトのタイム ゾーンがテヘラン タイム ゾーンに設定されていることを意味している可能性があります。コマンドを参照してくださいSET TIME ZONE
。しかし、その設定は、日時値の文字列表現を生成するときに適用される単なるウィンドウドレッシングです。JDBC と java.sql.Timestamp クラスを使用する場合、Postgres によって文字列が生成されないため、そのセッション設定は関係ありません。タイム ゾーンへの注意は、Postgres ではなく Java 側に向ける必要があります (以下のコードを参照)。
一般的に言えば、ホスト サーバーのオペレーティング システムは UTC に設定する必要があります。ただし、アプリのコードはそれに依存するべきではなく、希望する/予想されるタイム ゾーンを指定する必要があります。
java.time
Java 8 以降では、新しい java.time パッケージが古い java.util.Date/.Calendar クラスに取って代わります。これらの新しいクラスは、JSR 310 で定義された Joda-Time ライブラリに触発され、ThreeTen-Extraプロジェクトによって拡張されました。
最終的には、JDBC ドライバーが更新され、これらの新しい型を直接処理できるようになります。それまでの間、古いクラスと新しいクラスの両方に追加された変換メソッドを使用してください。
java.sql.Timestamp ts = myResultSet.getTimestamp( 1 );
Instant instant = ts.toInstant();
ZoneId zoneId = ZoneId.of( "Asia/Tehran" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );
または、 Unix Timeエポックからの秒数を指定して、Instant を作成します。
long secondsSinceUnixEpoch = 1_333_436_817L ;
Instant instant = Instant.ofEpochSecond( secondsSinceUnixEpoch );
ZoneId zoneId = ZoneId.of( "Asia/Tehran" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );