web-dev-qa-db-ja.com

Java 8のDateTimeFormatterおよびZonedDateTimeを使用してTemporalAccessorからZonedDateTimeを取得できません

最近、Java 8に移動しました。できれば、ローカル時間とゾーン時間をより簡単に処理できます。

しかし、私の意見では、単純な日付を解析するときに単純な問題に直面しています。

public static ZonedDateTime convertirAFecha(String fecha) throws Exception {
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern(
            ConstantesFechas.FORMATO_DIA).withZone(
            obtenerZonaHorariaServidor());

    ZonedDateTime resultado = ZonedDateTime.parse(fecha, formatter);
    return resultado;
}

私の場合:

  • fechaは'15/06/2014 'です
  • ConstantesFechas.FORMATO_DIAは「dd/MM/yyyy」です
  • obtenerZonaHorariaServidorはZoneId.systemDefault()を返します

したがって、これは簡単な例です。ただし、解析は次の例外をスローします。

Java.time.format.DateTimeParseException: Text '15/06/2014' could not be parsed: Unable to obtain ZonedDateTime from TemporalAccessor: {},ISO resolved to 2014-06-15 of type Java.time.format.Parsed

任意のヒント?解析とTemporalAccesorの使用のさまざまな組み合わせを試してきましたが、これまでのところ運はありません。

宜しくお願いします

33
Faliorn

なぜ機能しないのかはわかりません(おそらく入力にタイム/タイムゾーン情報がないためです)。簡単な方法は、日付をLocalDateとして解析し(時間またはタイムゾーン情報なし)、ZonedDateTimeを作成することです:

public static ZonedDateTime convertirAFecha(String fecha) {
  DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
  LocalDate date = LocalDate.parse(fecha, formatter);

  ZonedDateTime resultado = date.atStartOfDay(ZoneId.systemDefault());
  return resultado;
}
33
assylias

これはバグです。 JDK-bug-log を参照してください。その情報によると、Java 9 and Java 8u20。最新のJava 8-バージョン:2014年5月12日: 早期アクセスリリース8u2 が利用可能です。

UPDATE:

個人的には、パターンとして "dd/MM/yyyy"のみを使用しているため、@ assyliasがすでに提案しているように、LocalDateをプライマリタイプとして使用する必要があります。あなたのコンテキストに関しては、ZonedDateTimeを使用する設計の失敗はほぼ確実です。このタイプのオブジェクトで何をしたいですか?特殊なタイムゾーン計算はユースケースとしてしか考えられません。また、これらのZonedDateTime-オブジェクトをデータベースに直接保存することさえできないため、このタイプは多くの人が信じているよりもはるかに有用ではありません。

ユースケースの問題として説明したのは、古いGregorianCalendar- class(オールインワンタイプ)と比較して、Java-8で導入された新しい側面です。ユーザーは、問題やユースケースに適した一時的なタイプを選択することについて考え始める必要があります。

15
Meno Hochschild

簡単に言えば、行

ZonedDateTime.parse('2014-04-23', DateTimeFormatter.ISO_OFFSET_DATE_TIME)

例外をスローします:

Text '2014-04-23' could not be parsed at index 10
Java.time.format.DateTimeParseException: Text '2014-04-23' could not be parsed at index 10

私にはバグのように見えます。

私はこの回避策を使用しました:

String dateAsStr = '2014-04-23';
if (dateAsStr.length() == 10) {
    dateAsStr += 'T00:00:00';
}
ZonedDateTime.parse(dateAsStr, DateTimeFormatter.ISO_OFFSET_DATE_TIME.withZone(ZoneId.systemDefault()));
5
stokito

コンバージョンの例に過ぎませんが、以下の例外が発生する人もいると思います

(Java.time.DateTimeException: Unable to obtain LocalDateTime from TemporalAccessor: 2014-10-24T18:22:09.800Z of type Java.time.Instant)

彼らが試せば

LocalDateTime localDateTime = LocalDateTime.from(new Date().toInstant());

問題を解決するには、ゾーンを渡してください-

LocalDateTime localDateTime = LocalDateTime.from(new Date()
        .toInstant().atZone(ZoneId.of("UTC")));
2
Dahar Youssef

Googleからの場合:

代わりに:

ZonedDateTime.from(new Date().toInstant());

これを試して:

ZonedDateTime.ofInstant(new Date(), ZoneId.of("UTC")); 
2
anon58192932