sql >> データベース >  >> RDS >> Mysql

Javaの日付とMySQLのタイムスタンプのタイムゾーン

    tl; dr

    myPreparedStatement
    .setObject(  
        … ,                                   // Specify which placeholder `?` in your SQL statement. 
        OffsetDateTime.now( ZoneOffset.UTC )  // Capture the current moment as seen in the wall-clock time of UTC (an offset-from-UTC of zero).
    ) ;
    

    従来の日時クラスを避ける

    何年も前にjava.timeに取って代わられたひどい日時クラスを使用しています クラス。

    Dateは絶対に使用しないでください またはTimestamp

    UTC

    UTCで現在の瞬間をキャプチャします。ほとんどのデータベースはUTCで瞬間を保存します。また、通常、ビジネスロジック、デバッグ、ロギング、ストレージ、データ交換のほとんどをUTCで行う必要があります。

    OffsetDateTime

    適切な名前のOffsetDateTimeを使用して、UTCからのオフセットで瞬間を表します クラス。

    UTC自体、またはゼロのオフセットが必要です。そのための定数ZoneOffset.UTCを使用できます 。

    OffsetDateTime odt = OffsetDateTime.now( ZoneOffset.UTC ) ) ;
    

    JDBC 4.2

    JDBC 4.2以降、 java.timeを直接交換できます。 データベースを持つオブジェクト。

    この瞬間をSQL標準のTIMESTAMPWITH TIME ZONEに類似したデータ型の列に保存するには :

    myPreparedStatement.setObject( … , odt ) ;
    

    取得:

    OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
    

    ZonedDateTime

    この取得した瞬間をユーザーに提示するには、ユーザーの予想/希望のタイムゾーンに合わせて調整することをお勧めします。

    ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
    ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;
    

    デフォルトのタイムゾーンに依存しないでください

    上記のコードでは、常に目的の/予想されるオフセットまたはゾーンを指定していることに注意してください。

    指定しない場合、オフセットまたはゾーンが暗黙的に適用されます。 JVM、データベース、およびホストOSの現在のデフォルトはすべてプログラマーの手に負えないため、意図を明示的に指定することをお勧めします。つまり、デフォルトに依存するコードは、実行時の動作が異なります。

    Java 6&7

    JSR310とjava.timeを率いる同じ男性のStephenColebourne 実装、および有名な Joda-Time プロジェクトは、別のプロジェクト ThreeTen-Backport も主導しています。 java.timeのほとんど 機能は、ほぼ同じAPIを使用して、このライブラリのJava6および7にバックポートされています。

    したがって、すべての作業はバックポートクラスで行います。次に、最後に、 java.sql.Timestampとの間で変換します。 DateTimeUtils経由 クラス。

    これらの変換方法は主にInstantを使用します オブジェクト。 Instant UTCの瞬間であり、常にUTCです。 ResetDateTimeから調整できます Instantを抽出してUTCに変換 。 Instant classは、 java.timeの基本的なビルディングブロッククラスです。 、 ResetDateDate 文字列を生成するときの代替フォーマットパターンなど、より柔軟性があります。しかし、両方の Instant およびOffsetDateTime 瞬間、タイムライン上のポイントを表します。

    Instant instant = odt.toInstant() ;  
    java.sql.Timestamp ts = org.threeten.bp.DateTimeUtils.toSqlTimestamp( instant ) ;
    

    反対方向に進み、タイムスタンプを取得します データベースから、すぐに Instantに変換します 。

    java.sql.Timestamp ts = myResultSet.getTimestamp( … ) ;
    Instant instant = org.threeten.bp.DateTimeUtils.toInstant( ts ) ;
    

    java.timeについて

    java.time フレームワークはJava8以降に組み込まれています。これらのクラスは、厄介な古いレガシー に取って代わります。 javaなどの日時クラス。 util.Date カレンダー 、&​​ SimpleDateFormat

    Joda-Time プロジェクト、現在メンテナンスモードjava.time<への移行をアドバイスします/ a> クラス。

    詳細については、Oracleチュートリアルを参照してください。 。そして、StackOverflowで多くの例と説明を検索してください。仕様は JSR310 です。 。

    java.timeを交換できます データベースに直接オブジェクトを追加します。 JDBCドライバー を使用します JDBC4.2 に準拠 またはそれ以降。文字列は必要ありません。java.sql。*も必要ありません。 クラス。

    java.timeクラスはどこで入手できますか?

    ThreeTen-Extra プロジェクトは、追加のクラスでjava.timeを拡張します。このプロジェクトは、java.timeに将来追加される可能性のある試験場です。ここには、間隔 YearWeek YearQuarter 、および詳細




    1. MySQLは、GROUP_CONCAT関数の連結結果を切り捨てます

    2. SQL トリガーは INSTEAD OF DELETE を実行できませんが、ntext、image 列には必要です

    3. ProxySQLを使用した接続処理とスロットリング

    4. ウィンドウ関数とgroupby句はどのように相互作用しますか?