web-dev-qa-db-ja.com

java.time.format.DateTimeParseException:インデックス21でテキストを解析できませんでした

日時値を取得します

created_at  '2012-02-22T02:06:58.147Z'
Read-only. The time at which this task was created.

これは、Asana API によって提供されます

Java 8を使用して、次のように日時を解析しています

import Java.time.*;
import Java.time.format.*;

public class Times {

  public static void main(String[] args) {
    final String dateTime = "2012-02-22T02:06:58.147Z";
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'hh:mm:ss.SX");


    final ZonedDateTime parsed = ZonedDateTime.parse(dateTime, formatter);
    System.out.println(parsed);
  }
}

これを実行すると、次のエラーが表示されます

Exception in thread "main" Java.time.format.DateTimeParseException: Text '2012-02-22T02:06:58.147Z' could not be parsed at index 21
    at Java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.Java:1947)
    at Java.time.format.DateTimeFormatter.parse(DateTimeFormatter.Java:1849)
    at Java.time.ZonedDateTime.parse(ZonedDateTime.Java:597)
    at Times.main(Times.Java:11)
    at Sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at Sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.Java:62)
    at Sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.Java:43)
    at Java.lang.reflect.Method.invoke(Method.Java:497)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.Java:140)

ここにないものは何ですか?

21
daydreamer

デフォルトのパーサーは入力を解析できます。したがって、カスタムフォーマッタは必要ありません。

String dateTime = "2012-02-22T02:06:58.147Z";
ZonedDateTime d = ZonedDateTime.parse(dateTime);

期待どおりに動作します。

19
assylias

入力のタイムゾーンが常に "zulu"( "Z" = UTC)の場合、DateTimeFormatter.ISO_INSTANT(暗黙的に)を使用できます。

final Instant parsed = Instant.parse(dateTime);

タイムゾーンが異なり、「+ 01:00」または「+01:00:00」(「Z」ではない場合)の形式の場合、DateTimeFormatter.ISO_OFFSET_DATE_TIMEを使用できます。

DateTimeFormatter formatter = DateTimeFormatter.ISO_OFFSET_DATE_TIME;
final ZonedDateTime parsed = ZonedDateTime.parse(dateTime, formatter);

どちらでもない場合は、DateTimeFormatter.ISO_OFFSET_DATE_TIMEが構築されるのと同じ方法でDateTimeFormatterを構築できます。


現在のパターンにはいくつかの問題があります。

  • 厳密モードを使用しない(ResolverStyle.STRICT);
  • yyyyの代わりにuuuuを使用します(yyyyは厳密モードでは機能しません)。
  • 24時間のhhの代わりに12時間のHHを使用します。
  • 小数秒に1桁のSのみを使用しますが、入力には3桁が使用されます。
19
Roman

元の問題は、時刻(1〜12の範囲)を表す間違ったパターンシンボル「h」でした。この場合、am-pm-情報が欠落しています。代わりに、代わりに パターンシンボル "H" を使用してください(時間帯は0〜23の範囲)。したがって、パターンは次のようになります。

uuuu-MM-dd'T'HH:mm:ss.SSSX(ストリクトモードにも適した最適なパターン)

2
Meno Hochschild

次は私のために働いた

import Java.time.*;
import Java.time.format.*;

public class Times {

  public static void main(String[] args) {
    final String dateTime = "2012-02-22T02:06:58.147Z";
    DateTimeFormatter formatter = DateTimeFormatter.ISO_INSTANT;
    final ZonedDateTime parsed = ZonedDateTime.parse(dateTime, formatter.withZone(ZoneId.of("UTC")));
    System.out.println(parsed.toLocalDateTime());
  }
}

そして、私に出力を与えました

2012-02-22T02:06:58.147
1
daydreamer