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())));
}
}
}