DateTimeFormatter.parse (s) lanza cuando se llega al final de s: ¿por qué?

James Youngman:

He estado tratando de utilizar DateTimeFormatter a las cadenas de fecha / tiempo de análisis de la forma "20141112152340". Cuando llamo formatter.parse (entrada); se genera una excepción:

java.time.format.DateTimeParseException: Texto '20141112152340' no se pudo analizar en el índice 14

Aquí es un reproductor completo mínima:

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());
    }
}

Aquí está la salida de este programa:

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)

Por lo que yo puedo decir, el analizador está rescatando en el punto que llega al final de la cadena. Por offchance que esto sucede porque está en busca de más datos que he intentado cambiar el estilo de resolución del defecto a la estricta, pero esto parece hacer ninguna diferencia.

Mi pregunta es, ¿por qué sucede esto, y cómo puedo corregir mi código para que pueda analizar esta representación de la fecha / hora?

malta:

La siguiente formateador funciona para mí:

DateTimeFormatter.ofPattern("yyyyMMddHHmmss");

El toString()tanto de formateadores revela la diferencia:

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

vs

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

Como se puede ver, la segunda formateador, que es la versión de trabajo, parece tener ancho de los campos explícitos, así como explícita SignStyle

Podemos crear el mismo formateador usando el constructor:

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);

Sin embargo, parece que se puede sustituir YEAR_OF_ERAcon YEARun resultado similar.

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=331559&siteId=1
Recomendado
Clasificación