24

Java Date and Calendar を使用して、あるタイムゾーンから別のタイムゾーンへの簡単な変換を取得しようとしています。次のコードを実行しようとしています

    Calendar instance = Calendar.getInstance(TimeZone.getTimeZone("Europe/London"));
    Date date = instance.getTime();
    System.out.println(date);

    GregorianCalendar instance2 = new GregorianCalendar(TimeZone.getTimeZone("Europe/Athens"));
    instance2.setTime(instance.getTime());
    System.out.println(instance2.getTime());

しかし、それでも+1時間ではなく同じ日付が返されます...問題全体は些細なことに思えますが、これに対する簡単な答えが見つかりません。よろしくお願いします。

4

3 に答える 3

37

を使用して日付を印刷するSystem.out.println(date); or System.out.println(instance2.getTime());と、Date 返されるinstance2.getTime()は isTimeZone independentであり、常にローカル タイムゾーンで日付を印刷します。

代わりに、次を使用できますDateFormat/SimpleDateFormat

  DateFormat formatter= new SimpleDateFormat("MM/dd/yyyy HH:mm:ss Z");
  formatter.setTimeZone(TimeZone.getTimeZone("Europe/London"));
  System.out.println(formatter.format(date));

  formatter.setTimeZone(TimeZone.getTimeZone("Europe/Athens"));
  System.out.println(formatter.format(instance2.getTime()))
于 2012-11-02T15:12:40.903 に答える
15

受け入れられた答えは正しいです。java.util.Date クラスにはタイム ゾーンが割り当てられていません†</sup> が、toStringその実装では紛らわしく、JVM の現在のデフォルト タイム ゾーンが適用されます。

java.util.Date と .Calendar を避ける

これは、Java にバンドルされていることで悪名高い java.util.Date、.Calendar、および SimpleDateFormat クラスを回避する多くの理由の 1 つです。それらを避けてください。代わりに次のいずれかを使用します。

Joda-Time

Joda-Time 2.3 のコード例を次に示します。さらに多くの例と議論については、StackOveflow を検索してください。

DateTimeZone timeZoneLondon = DateTimeZone.forID( "Europe/London" );
DateTimeZone timeZoneAthens = DateTimeZone.forID( "Europe/Athens" );

DateTime nowLondon = DateTime.now( timeZoneLondon );
DateTime nowAthens = nowLondon.withZone( timeZoneAthens );
DateTime nowUtc = nowLondon.withZone( DateTimeZone.UTC );

java.time

Java 8 以降には、新しいjava.time パッケージが組み込まれています。このパッケージは Joda-Time に触発されました。これらはいくつかの類似点とクラス名を共有していますが、異なっています。それぞれに他にない機能があります。注目すべき違いの 1 つは、java.time がコンストラクターを回避し、代わりに静的インスタンス化メソッドを使用することです。

この質問の場合、それらは同じように機能します。タイム ゾーンを指定し、現在の時刻を取得するメソッドを呼び出してnowから、古い不変インスタンスに基づいて新しいインスタンスを作成し、タイム ゾーンを調整します。

2 つの異なるタイム ゾーン クラスに注意してください。1 つは名前付きのタイム ゾーンで、夏時間やその他の異常に関するすべての規則と UTC からのオフセットが含まれていますが、もう 1 つはオフセットのみです。

ZoneId zoneMontréal = ZoneId.of("America/Montreal"); 
ZonedDateTime nowMontréal = ZonedDateTime.now ( zoneMontréal );

ZoneId zoneTokyo = ZoneId.of("Asia/Tokyo"); 
ZonedDateTime nowTokyo = nowMontréal.withZoneSameInstant( zoneTokyo );

ZonedDateTime nowUtc = nowMontréal.withZoneSameInstant( ZoneOffset.UTC );

†</sup>実際には、java.util.Dateクラスのソース コードにタイム ゾーンが埋め込まれてます。ただし、このクラスでは、ほとんどの場合、そのタイム ゾーンは無視されます。そのため、簡単に言うと、juDate にはタイム ゾーンが割り当てられていないとよく言われます。混乱しますか?はい。juDate の混乱を避け、Joda-Time や java.time を使用してください。

于 2014-07-15T07:19:36.773 に答える
3

次のコード スニペットを使用できます。

String dateString = "14 Jul 2014 00:11:04 CEST";
date = formatter.parse(dateString);
System.out.println(formatter.format(date));

// Set the formatter to use a different timezone - Indochina Time
formatter.setTimeZone(TimeZone.getTimeZone("Asia/Bangkok"));
System.out.println("ICT time : "+formatter.format(date));
于 2014-07-15T04:35:34.833 に答える