web-dev-qa-db-ja.com

日付を別のタイムゾーンに変換する

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

    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時間ではなく同じ日付を返します...問題全体は些細なようですが、これに対する簡単な答えは見つかりません。よろしくお願いします。

24
Bober02

System.out.println(date); or System.out.println(instance2.getTime());を使用して日付を出力すると、instance2.getTime()によって返されるDateTimeZone 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()))
37
Yogendra Singh

受け入れられた答えは正しいです。 Java.util.Dateクラスにはタイムゾーンが割り当てられていません、まだtoString実装は紛らわしいことにJVMの現在のデフォルトのタイムゾーンを適用します。

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

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

ジョーダタイム

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

実際、Java.util.Date classdoesは、タイムゾーンを ソースコード に埋め込んでいます。しかし、クラスは最も実用的な目的のためにそのタイムゾーンを無視します。そのため、略記として、j.u.Dateにはタイムゾーンが割り当てられていないとよく言われます。紛らわしい?はい。 j.u.Dateである混乱を避け、Joda-TimeやJava.timeを使用してください。

15
Basil Bourque

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

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));
3
Srijani Ghosh