No se puede obtener LocalDateTime de TemporalAccessor al analizar LocalDateTime (Java 8)

151

Simplemente estoy tratando de convertir una cadena de fecha en un objeto DateTime en Java 8. Al ejecutar las siguientes líneas:

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
LocalDateTime dt = LocalDateTime.parse("20140218", formatter);

Obtuve el siguiente error:

Exception in thread "main" java.time.format.DateTimeParseException: 
Text '20140218' could not be parsed: 
Unable to obtain LocalDateTime from TemporalAccessor: 
{},ISO resolved to 2014-02-18 of type java.time.format.Parsed
    at java.time.format.DateTimeFormatter.createError(DateTimeFormatter.java:1918)
    at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1853)
    at java.time.LocalDateTime.parse(LocalDateTime.java:492)

La sintaxis es idéntica a la que se ha sugerido aquí , pero recibo una excepción. Estoy usando JDK-8u25.

retrografía
fuente

Respuestas:

177

Resulta que Java no acepta un valor de fecha simple como DateTime. El uso de LocalDate en lugar de LocalDateTime resuelve el problema:

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
LocalDate dt = LocalDate.parse("20140218", formatter);
retrografía
fuente
42
Por lo que vale: tuve este mismo problema incluso cuando lo usaba LocalDatey no LocalDateTime. ¡El problema era que había creado mi DateTimeFormatteruso .withResolverStyle(ResolverStyle.STRICT);, así que tuve que usar el patrón de fecha en uuuuMMddlugar de yyyyMMdd(es decir, "año" en lugar de "año de la era")!
ZeroOne
72

Si realmente necesita transformar una fecha en un objeto LocalDateTime, puede usar LocalDate.atStartOfDay (). Esto le dará un objeto LocalDateTime en la fecha especificada, con los campos de hora, minuto y segundo establecidos en 0:

final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
LocalDateTime time = LocalDate.parse("20140218", formatter).atStartOfDay();
Øyvind Mo
fuente
2
Corrección: establezca la hora que sea al comienzo de ese día .
Trejkaz
20
LocalDateTime.fromParece innecesario, como atStartOfDay()ya regresa LocalDateTime.
Dariusz el
1
scala: val time = LocalDate.parse ("20171220", DateTimeFormatter.ofPattern ("aaaaMMdd")). atStartOfDay.format (DateTimeFormatter.ofPattern ("aaaa-MM-dd HH: mm: ss"))
Woody Sun
48

Para lo que vale la pena si alguien debería leer nuevamente este tema (como yo), la respuesta correcta estaría en DateTimeFormatterdefinición, por ejemplo:

private static DateTimeFormatter DATE_FORMAT =  
            new DateTimeFormatterBuilder().appendPattern("dd/MM/yyyy[ [HH][:mm][:ss][.SSS]]")
            .parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
            .parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
            .parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
            .toFormatter(); 

Uno debería establecer los campos opcionales si aparecerán. Y el resto del código debería ser exactamente el mismo.

Iulian David
fuente
1
Esta es una verdadera solución universal, por ejemplo, para dicho método: getFileTimestamp largo (archivo de cadena, patrón de patrón, DateTimeFormatter dtf, int group); Aquí tiene diferentes patrones y DateTimeFormetter, w / y w / o time especificado.
toootooo
¿Puede ser un campo estático? No he encontrado en el Javadoc que una instancia creada de esa manera sea segura para subprocesos
Kamil Roman
Recuerde agregar el parseDefaultingDESPUÉS de haber llamado appendPattern. De lo contrario, dará DateTimeParseException.
wittyameta
31

Este es un mensaje de error realmente poco claro e inútil. Después de mucho ensayo y error, descubrí que LocalDateTimedará el error anterior si no intenta analizar una hora. Al usar en su LocalDatelugar, funciona sin errores.

Esto está mal documentado y la excepción relacionada es muy poco útil.

Tumba
fuente
25

Ampliando la respuesta de la retrografía ...: tuve este mismo problema incluso cuando lo usaba LocalDatey no LocalDateTime. ¡El problema era que había creado mi DateTimeFormatteruso .withResolverStyle(ResolverStyle.STRICT);, así que tuve que usar el patrón de fecha en uuuuMMddlugar de yyyyMMdd(es decir, "año" en lugar de "año de la era")!

DateTimeFormatter formatter = new DateTimeFormatterBuilder()
  .parseStrict()
  .appendPattern("uuuuMMdd")
  .toFormatter()
  .withResolverStyle(ResolverStyle.STRICT);
LocalDate dt = LocalDate.parse("20140218", formatter);

(Esta solución fue originalmente un comentario a la respuesta de la retrografía, pero me animaron a publicarla como una respuesta independiente porque aparentemente funciona muy bien para muchas personas).

Cero uno
fuente
1
La respuesta a por qué "u" en lugar de "y" ha sido respondida en este enlace uuuu-versus-aaaa-en-fecha-hora-formateador-formato-códigos-en-java @Peru
prashanth
23

Para cualquiera que aterrizó aquí con este error, como hice yo:

Unable to obtain LocalDateTime from TemporalAccessor: {HourOfAmPm=0, MinuteOfHour=0}

Provenía de la siguiente línea:

LocalDateTime.parse(date, DateTimeFormatter.ofPattern("M/d/yy h:mm"));

Resultó que era porque estaba usando un patrón de 12 horas en una hora 0, en lugar de un patrón de 24 horas.

Cambiando el patrón de la hora a 24 horas usando una H mayúscula lo arregla:

LocalDateTime.parse(date, DateTimeFormatter.ofPattern("M/d/yy H:mm"));
mawburn
fuente
12

Si la fecha de cuerdas no incluye ningún valor para las horas, minutos y etc no se puede convertir directamente a un LocalDateTime. Solo puede convertirlo a a LocalDate, porque la cadena solo representa los componentes de año, mes y fecha , sería lo correcto.

DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMdd");
LocalDate ld = LocalDate.parse("20180306", dtf); // 2018-03-06

De todos modos puedes convertir esto a LocalDateTime.

DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMdd");
LocalDate ld = LocalDate.parse("20180306", dtf);
LocalDateTime ldt = LocalDateTime.of(ld, LocalTime.of(0,0)); // 2018-03-06T00:00
principal
fuente
También asegúrese de que el formato sea correcto. Esta solución no funcionó para mí hasta que configuré el formato yyyy-mm-ddcuando debería haber sido yyyy-MM-dd.
Patstuart
0

Prueba este:

DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("MM-dd-yyyy"); 
LocalDate fromLocalDate = LocalDate.parse(fromdstrong textate, dateTimeFormatter);

Puede agregar cualquier formato que desee. ¡Funciona para mi!

Vinay Kasarla
fuente
0

Esto funciona bien

public class DateDemo {
    public static void main(String[] args) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy hh:mm");
        String date = "16-08-2018 12:10";
        LocalDate localDate = LocalDate.parse(date, formatter);
        System.out.println("VALUE="+localDate);

        DateTimeFormatter formatter1 = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm");
        LocalDateTime parse = LocalDateTime.parse(date, formatter1);
        System.out.println("VALUE1="+parse);
    }
}

salida:

VALUE=2018-08-16
VALUE1=2018-08-16T12:10
Jeff Cook
fuente