それはSの終わりに到達したときDateTimeFormatter.parse(複数可)スロー:なぜ?

ジェームズ・ヤングマン:

私は「20141112152340」形式の日付/時刻文字列を解析してDateTimeFormatterを使用しようとしてきました。私は(入力)formatter.parse呼び出すと、それは例外が発生します:

java.time.format.DateTimeParseException:テキスト「20141112152340」は、インデックス14で解析できませんでした

ここでは、最小限の完全な再生は以下のとおりです。

package com.example.minimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.ResolverStyle;
import java.time.temporal.ChronoField;
import java.time.temporal.TemporalAccessor;

public class Reproducer {
    public static void main(String[] args) {
        DateTimeFormatter formatter = new DateTimeFormatterBuilder()
            .appendValue(ChronoField.YEAR) // 4
            .appendValue(ChronoField.MONTH_OF_YEAR) // 2
            .appendValue(ChronoField.DAY_OF_MONTH) // 2
            .appendValue(ChronoField.HOUR_OF_DAY) // 2
            .appendValue(ChronoField.MINUTE_OF_HOUR) // 2
            .appendValue(ChronoField.SECOND_OF_MINUTE) // 2
            .toFormatter()
            // Using the default ResolverStyle appears to make no difference.
            .withResolverStyle(ResolverStyle.STRICT); // expect 14 characters
        String input = "20141112152340";
        System.out.printf("length of input is %02d:               [%s]; format is %s\n", input.length(), input, formatter.toString());
        // When the minute of hour is < 10, it is rendered without zero-padding.   Perhaps this
        // is related.  But, the same problem is reproducible on input strings that do not contain zeroes.
        System.out.printf("Current local time in that format is [%s]\n", formatter.format(LocalDateTime.now()));
        // The following line throws java.time.format.DateTimeParseException: Text '20140816152340' could not be parsed at index 14
        TemporalAccessor parsed = formatter.parse(input);
        // NOTREACHED
        LocalDateTime stamp = parsed.query(LocalDateTime::from);
        System.out.println("Time stamp is " + stamp.toString());
    }
}

ここでは、このプログラムの出力は次のようになります。

length of input is 14:               [20141112152340]; format is Value(Year)Value(MonthOfYear)Value(DayOfMonth)Value(HourOfDay)Value(MinuteOfHour)Value(SecondOfMinute)
Current local time in that format is [20191010183335]
Exception in thread "main" java.time.format.DateTimeParseException: Text '20141112152340' could not be parsed at index 14
    at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2046)
    at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1874)
    at com.example.minimal.Reproducer.main(Reproducer.java:28)

私の知る限り、パーサーは、文字列の末尾に到達した時点で救済されます。それは私が厳密にデフォルトのリゾルバのスタイルを切り替えてみましたより多くのデータを探しているが、これは違いはありませんように見えるので、これが起こることをoffchanceオン。

私の質問は、なぜこの出来事で、であり、それはこの日付/時刻表現を解析できるように、どのように私は自分のコードを修正するのですか?

モルト:

以下のフォーマッタは私のために仕事を行います。

DateTimeFormatter.ofPattern("yyyyMMddHHmmss");

toString()両方のフォーマッタの違いを明らかに:

Value(Year)Value(MonthOfYear)Value(DayOfMonth)Value(HourOfDay)Value(MinuteOfHour)Value(SecondOfMinute)

Value(YearOfEra,4,19,EXCEEDS_PAD)Value(MonthOfYear,2)Value(DayOfMonth,2)Value(HourOfDay,2)Value(MinuteOfHour,2)Value(SecondOfMinute,2)

あなたが見ることができるように、作業バージョンである第二フォーマッタは、だけでなく、明示的な明示的なフィールド幅を持っているようです SignStyle

私たちは、ビルダーを使用して、同じフォーマッタを作成することができます。

DateTimeFormatter formatter = new DateTimeFormatterBuilder()
        .appendValue(ChronoField.YEAR_OF_ERA, 4, 19, SignStyle.EXCEEDS_PAD)
        .appendValue(ChronoField.MONTH_OF_YEAR, 2)
        .appendValue(ChronoField.DAY_OF_MONTH, 2)
        .appendValue(ChronoField.HOUR_OF_DAY, 2)
        .appendValue(ChronoField.MINUTE_OF_HOUR, 2)
        .appendValue(ChronoField.SECOND_OF_MINUTE, 2)
        .toFormatter()
        .withResolverStyle(ResolverStyle.STRICT);

あなたは置き換えることができますようにしかし、それは見えYEAR_OF_ERAYEARも同様の結果で。

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=331556&siteId=1