1

JSR 310 を使用して、ミリ秒単位の日時値をタイムゾーン間で変換しようとしています。従来の API を使用するには、ミリ秒単位の値を処理する必要があります。私の場合、それはローカルと UTC/GMT の間にありますが、ソースと宛先のタイムゾーンが関係していることに関係なく、まったく同じコードであると予想されます。これが私の小さなテストプログラムです。最後のローカル DST 変更の前後で数時間にわたって反復するように構成されています。出力が間違っているので、UTCtoLocalMillis が間違っていると思いますが、テスト方法にも問題がある可能性があります。間違った出力とは、私のタイムゾーンでは、UTC を取得するために時間を減算する必要がありますが、コードは実際には時間を追加するということです。第 2 に、DST の開始点も 1 時間ずれています。

最初にローカル タイムゾーンをフェッチしますが、出力を作成するときに Date().toString() が変換を実行しないように、それを UTC にリセットします。

私が望むのは、新しい JSR 310 API を使用して、ミリ秒単位の時間を取り、ソース ZoneID とターゲット ZoneID を取り、変換されたミリ秒を返すメソッドを作成することです。

public class Test {
static int DAYS_OFFSET_TO_BE_BEFORE_DST_CHANGE = -16;

static TimeZone UTC_TZ = TimeZone.getTimeZone("UTC");

static TimeZone LOCAL_TZ = TimeZone.getDefault();

static ZoneId UTC_ID = ZoneId.of(UTC_TZ.getID());

static ZoneId LOCAL_ZONE_ID = ZoneId.of(LOCAL_TZ.getID());

static long UTCtoLocalMillis(final long utcMillis) {
    final Instant instant = Instant.ofEpochMilli(utcMillis);
    final ZonedDateTime before
        = ZonedDateTime.ofInstant(instant, UTC_ID);
    final ZonedDateTime after
        = before.withZoneSameLocal(LOCAL_ZONE_ID);
    return after.toInstant().toEpochMilli();
}

public static void main(final String[] args) {
    TimeZone.setDefault(UTC_TZ);
    System.out.println("LOCAL_TZ: " + LOCAL_TZ.getDisplayName());
    final Calendar cal = Calendar.getInstance(LOCAL_TZ);
    cal.add(Calendar.DATE, DAYS_OFFSET_TO_BE_BEFORE_DST_CHANGE);
    final Date start = cal.getTime();
    // DST Change: Sunday, 31 March 2013 01:59:59 (local time)
    final long oneHour = 3600000L;
    for (int i = 0; i < 12; i++) {
        final Date date = new Date(start.getTime() + i * oneHour);
        System.out.println("UTC: " + date + "   toLocal: "
                + new Date(UTCtoLocalMillis(date.getTime())));
    }
}
}
4

2 に答える 2

3

私が望むのは、新しい JSR 310 API を使用して、ミリ秒単位の時間を取り、ソース ZoneID とターゲット ZoneID を取り、変換されたミリ秒を返すメソッドを作成することです。

あなたの要件は非常に混乱しているようです。時間 API で一般的に参照される「ミリ秒」値はエポックミリ秒であり、1970-01-01T00:00Z からのミリ秒数です。ミリ秒値は常に UTC に相対的です。「ローカル ミリ秒」という概念はありますが、実際には使用されません。特に、java.util.Date コンストラクターは epoch-millis を取ります。

したがって、コードnew Date(UTCtoLocalMillis(date.getTime()))は基本的に無意味です。

于 2013-04-16T09:48:48.513 に答える