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.

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

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

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.


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.


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


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

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

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!


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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.