32

データベースからタイムスタンプ値をフェッチし、それらをカレンダーに変換して、タイムスタンプに戻そうとしていますが、精度が失われます。

問題を再現するためのコードは次のとおりです

import java.sql.Timestamp;
import java.util.Calendar;

public class Test {
    public static void main(String[] args)
    {
        Timestamp timestamp = new Timestamp(112, 10, 5, 15, 39, 11, 801000000);
        System.out.println("BEFORE "+timestamp.toString());
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(timestamp.getTime());
        timestamp = new Timestamp(calendar.getTimeInMillis());
        System.out.println("AFTER "+timestamp.toString());
    }
}

これが変換のサンプル結果です

BEFORE 2012-10-18 14:30:13.362001
AFTER 2012-10-18 14:30:13.362

精度が低下します。10進値をそのまま維持するにはどうすればよいですか?

4

2 に答える 2

30

時間をミリ秒単位で設定していますが、入力精度はマイクロ秒単位であるため、もちろん、ミリ秒よりも細かい精度は失われます。

カレンダーは、ミリ秒よりも細かい粒度をサポートしていません。回避策はありません。

于 2012-11-06T10:06:58.200 に答える
8

java.time

Java 8以降では、解決策があります。新しいjava.timeフレームワークが組み込まれています。Joda -Timeに触発され、 ThreeTen -Extraプロジェクトによって拡張されたJSR310によって定義されています。

この新しいフレームワークの解像度はナノ秒です。これは、両方ともミリ秒である古いjava.util.Date値、Joda-Time値を処理するのに十分です。また、 Postgresなどの一部のデータベースで使用されるマイクロ秒を処理するのに十分です。H2などの一部のデータベースはナノ秒を使用します。したがって、java.timeはそれをすべて、または少なくともすべての主流の状況で処理できます。唯一の例外は、ニッチな科学的または工学的状況です。

画像

Java 8では、古いクラスにjava.timeとの間で変換するための新しいメソッドが追加されました。java.sql.Timestampでは、newメソッドとメソッドを使用します。このクラスには、1970 UTCの最初の瞬間であるエポックからのナノ秒のカウントが含まれています(基本的に、詳細についてはクラスのドキュメントを参照してください)。toInstantfromInstantInstant

からオブジェクトInstantを取得できZonedDateTimeます。

java.sql.Timestamp ts = myResultSet.getTimestamp( 1 );
Instant instant = ts.toInstant();
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( zoneId );
于 2015-09-02T16:46:44.757 に答える