web-dev-qa-db-ja.com

文字列をZonedDateTimeに変換できません:DateTimeParseException

文字列をJSONからZonedDateTimeに変換しようとしています

static String getWatchTime(JSONObject aJson, JSONObject bJson) {
    long difference = 0 ;
    try {
        String aTime = aJson.getString("time_utc_8");
        String bTime = bJson.getString("time_utc_8");

        String pattern = "yyyy-MM-dd HH:mm:ss.SSSSSS";
        DateTimeFormatter Parser = DateTimeFormatter.ofPattern(pattern).ISO_DATE;

        System.out.println(aTime);

        ZonedDateTime a = ZonedDateTime.parse(aTime, Parser);
        ZonedDateTime b = ZonedDateTime.parse(bTime, Parser);

        ChronoUnit unit = null;
        difference = unit.between(a, b);

        System.out.println(difference);

    } catch (JSONException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    String t = difference +"";
    return t;

}

常にエラーが発生します

Exception in thread "main" Java.time.format.DateTimeParseException: Text '2016-06-28 22:29:44.700228' could not be parsed: Unable to obtain OffsetDateTime from TemporalAccessor: {},ISO resolved to 2016-06-28T22:29:44.700228 of type Java.time.format.Parsed
at Java.time.format.DateTimeFormatter.createError(Unknown Source)
at Java.time.format.DateTimeFormatter.parse(Unknown Source)
at Java.time.OffsetDateTime.parse(Unknown Source)
at Q2.getWatchTime(Q2.Java:321)
at Q2.WatchTime(Q2.Java:265)
at Q2.main(Q2.Java:31)

この2つの日付の違いを知りたいです。 SimpleDateFormatを試しましたが、ミルの場合、エラー結果が表​​示されます。

3
Zi-yan Tseng

すでにコメントにすべて入っていると思うので、これは要約するだけです。

(1)フォーマットパターン文字列が正しい。次の行から.ISO_DATEを削除するだけで、次のようになります。

          DateTimeFormatter Parser = DateTimeFormatter.ofPattern(pattern);

ISO_DATEは、たとえば「2011-12-03 + 01:00」または「2011-12-03」を受け入れます。これは、UTCからのオフセットの有無にかかわらず、時刻のない日付です。これを使用するものは何もありません。私が知る限り、ここにあります。)

(2)文字列にはタイムゾーンもオフセットもないように見えるので、LocalDateTimeを使用します。

          LocalDateTime a = LocalDateTime.parse(aTime, Parser);
          LocalDateTime b = LocalDateTime.parse(bTime, Parser);

差を計算するときに夏時間(DST)などを考慮する必要がある場合は、解析後の時間を変換します。

          ZoneId timeZone = ZoneId.systemDefault();
          ZonedDateTime a = LocalDateTime.parse(aTime, Parser).atZone(timeZone);
          ZonedDateTime b = LocalDateTime.parse(bTime, Parser).atZone(timeZone);

期待どおりの結果が得られるように、変換に使用するタイムゾーンについてよく考えてください。

(3)ChronoUnitnullは機能しません。どちらを意図したのかわからないため、このオプションはかなりランダムに選択されます。

          ChronoUnit unit = ChronoUnit.DAYS;

これらの3つの変更により、メソッドは私のコンピューターでうまく実行されます。 1回の実行で、次のように出力されました。

2016-06-28 22:29:44.700228
365

同じ実行で、365の文字列が返されました。

5
Ole V.V.

私はアンドレアスによって答えを得ます(コメントで)私は最終的に私の目標を達成するためにこのコードを使用しました

_    static String getWatchTime(JSONObject aJson, JSONObject bJson) {
    double difference = 0 ;
    try {
        String aTime = aJson.getString("time_utc_8");
        String bTime = bJson.getString("time_utc_8");

          String pattern = "yyyy-MM-dd HH:mm:ss.SSSSSS";
          DateTimeFormatter Parser = DateTimeFormatter.ofPattern(pattern).withZone(ZoneId.systemDefault());

          System.out.println(aTime);


          ZonedDateTime a = ZonedDateTime.parse(aTime,Parser);
          ZonedDateTime b = ZonedDateTime.parse(bTime,Parser);

          System.out.println(a);
          System.out.println(b);
          //ChronoUnit unit = null ;
          difference = ChronoUnit.MICROS.between(a, b);


    } catch (JSONException e) {
        e.printStackTrace();
    } /*catch (ParseException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }*/

    String t = difference +"";
    return t;

}
_

TimeZoneを設定しなかったため、入力を文字列としてZonedDateTimeに変換できません。そして、マイクロ秒を取得する必要があるため、ChronoUnit.MICROS.between()を使用します。回答ありがとうございます

3
Zi-yan Tseng