web-dev-qa-db-ja.com

タイムゾーンでZonedDateTimeをLocalDateTimeに変換

このように構築されたZonedDateTimeのオブジェクトがあります

ZonedDateTime z = ZonedDateTime.of(LocalDate.now().atTime(11, 30), ZoneOffset.UTC);

スイスのタイムゾーンでLocalDateTimeに変換するにはどうすればよいですか?期待される結果は16 april 2018 13:30

14
Vitalii

スイスのタイムゾーンでLocalDateTimeに変換するにはどうすればよいですか?

UTC ZonedDateTimeをスイスのタイムゾーンでZonedDateTimeに変換できますが、同じ瞬間を維持し、その中からLocalDateTimeを取得できます。する必要があります。何らかの理由でZonedDateTimeとして必要な場合を除き、LocalDateTimeのままにしておきたいと思います。

ZonedDateTime utcZoned = ZonedDateTime.of(LocalDate.now().atTime(11, 30), ZoneOffset.UTC);
ZoneId swissZone = ZoneId.of("Europe/Zurich");
ZonedDateTime swissZoned = utcZoned.withZoneSameInstant(swissZone);
LocalDateTime swissLocal = swissZoned.toLocalDateTime();
31
Jon Skeet

LocalDateTimeとZonedDateTimeの違いを理解するのに役立ちます。本当に欲しいのはZonedDateTimeです。文字列表現からタイムゾーンを削除する場合、LocalDateTimeに変換します。

探しているのは次のとおりです。ZonedDateTime swissZonedDateTime = withZoneSameInstant(ZoneId.of( "Europe/Zurich"));

LocalDateTime-これは、基本的には日付と時刻の装飾文字列表現です。タイムゾーンに依存しないため、タイムライン上の特定の時点を表しません

インスタント-これは、エポック以降に経過した時間のミリ秒表現です。これは、タイムライン上の特定の瞬間を表します

ZonedDateTime-これはタイムライン上の時刻を表しますが、TimeZoneで日付と時刻として表します。

以下のコードは、3つすべてを使用する方法を示しています。

LocalDateTime localDateTime = LocalDateTime.of(2018, 10, 25, 12, 00, 00);  //October 25th at 12:00pm
ZonedDateTime zonedDateTimeInUTC = localDateTime.atZone(ZoneId.of("UTC")); 
ZonedDateTime zonedDateTimeInEST = zonedDateTimeInUTC.withZoneSameInstant(ZoneId.of("America/New_York")); 

System.out.println(localDateTime.toString()); // 018-10-25T12:00
System.out.println(zonedDateTimeInUTC.toString()); // 2018-10-25T12:00Z[UTC]
System.out.println(zonedDateTimeInEST.toString()); // 2018-10-25T08:00-04:00[America/New_York]

上記の両方のZonedDateTimesのInstant値を比較した場合、それらは両方とも同じ瞬間を指すため、同等になります。グリニッジのどこか(UTCタイムゾーン)は、10月25日の正午です。同時に、ニューヨークでは午前8時(アメリカ/ニューヨークタイムゾーン)になります。

3
Stevers

これを試してください。 US/Centralをタイムゾーンに置き換えます。

ZonedDateTime z = ZonedDateTime.of(LocalDate.now().atTime(11, 30), ZoneOffset.UTC);

System.out.println(z.withZoneSameInstant(ZoneId.of("US/Central")));
3

もう少し直感的に思える別のオプションは、ゾーン化された日付をインスタントに変換し、LocalDateTime.ofInstantを使用することです。

ZonedDateTime z = ZonedDateTime.of(LocalDate.now().atTime(11, 30), ZoneOffset.UTC);
ZoneId z = ZoneId.of("US/Central");
LocalDateTime l = LocalDateTime.ofInstant(z.toInstant(), z);

withZoneSameInstantよりもこのソリューションの方が好きです。なぜなら、このソリューションはもう少し不透明だからです。特定の内部状態(正しいタイムゾーン)でなければならないZonedDateTimeを取得しているからです。 ofInstantの使用は、任意のタイムゾーンのZonedDateTimeで使用できます。

0
Jon Nichols