web-dev-qa-db-ja.com

TemporalAccessorからOffsetDateTimeを取得できません

私がこれをするとき

String datum = "20130419233512";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss").withZone(ZoneId.of("Europe/Berlin"));
OffsetDateTime datetime = OffsetDateTime.parse(datum, formatter);

次の例外が発生します。

    Java.time.format.DateTimeParseException: Text '20130419233512' could not be parsed: 
Unable to obtain OffsetDateTime from TemporalAccessor: {InstantSeconds=1366407312},ISO,Europe/Berlin resolved 
to 2013-04-19T23:35:12 of type Java.time.format.Parsed

日時文字列を解析して、常にタイムゾーン「Europe/Berlin」からのものとして解釈されるようにするにはどうすればよいですか?

14
asmaier

問題は、ZoneIdZoneOffsetの間に違いがあることです。 OffsetDateTimeを作成するには、ゾーンオフセットが必要です。ただし、 ZoneIdZoneOffsetの間に1対1のマッピングはありません 実際には現在の夏時間に依存するためです。 「Europe/Berlin」のような同じZoneIdの場合、夏には1つのオフセットがあり、冬には別のオフセットがあります。

この場合、ZonedDateTimeの代わりにOffsetDateTimeを使用する方が簡単です。解析中、ZonedDateTimeは_"Europe/Berlin"_ゾーンIDに正しく設定され、オフセットは、解析する日付に対して有効な夏時間に応じて設定されます。

_public static void main(String[] args) {
    String datum = "20130419233512";
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss").withZone(ZoneId.of("Europe/Berlin"));
    ZonedDateTime datetime = ZonedDateTime.parse(datum, formatter);

    System.out.println(datetime.getZone()); // prints "Europe/Berlin"
    System.out.println(datetime.getOffset()); // prints "+02:00" (for this time of year)
}
_

本当にOffsetDateTimeが必要な場合は、 ZonedDateTime.toOffsetDateTime() を使用してZonedDateTimeOffsetDateTimeに変換できることに注意してください。

15
Tunaki

ソースデータにオフセットがないため、OffsetDateTimeは解析中に使用する正しいタイプではありません。

代わりに、LocalDateTimeを使用してください。これは、使用しているデータに最もよく似ているタイプだからです。次に、atZoneを使用してタイムゾーンを割り当てます。それでもOffsetDateTimeが必要な場合は、そこからtoOffsetDateTimeを呼び出すことができます。

String datum = "20130419233512";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
LocalDateTime datetime = LocalDateTime.parse(datum, formatter);
ZonedDateTime zoned = datetime.atZone(ZoneId.of("Europe/Berlin"));
OffsetDateTime result = zoned.toOffsetDateTime();
6