Java – fecha indesplazable

Estoy tratando de analizar una fecha, pero extrañamente recibo una excepción.

Este es el código:

import java.util.Date; String strDate = "Wed, 09 Feb 2011 12:34:27"; Date date; SimpleDateFormat FORMATTER = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss"); try { date = FORMATTER.parse(strDate.trim()); System.out.println(date); } catch (ParseException e) { e.printStackTrace(); } 

La excepción es:

java.text.ParseException: fecha inaplicable: “mié, 09 de febrero de 2011, 12:34:27” en java.text.DateFormat.parse (DateFormat.java:337) en DateTest.main (DateTest.java:17)

He leído la documentación y creo que mi patrón es correcto. Entonces no entiendo …

¿Alguna idea?

¡Gracias!

Probablemente sea por la configuración regional predeterminada en su computadora que no es inglés.

Deberías usar:

 new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss", Locale.ENGLISH); 

en lugar.

tl; dr

 java.util.Date.from ( LocalDateTime.parse( "Wed, 09 Feb 2011 12:34:27" , DateTimeFormatter.ofPattern( "EEE, dd MMM uuuu HH:mm:ss" , Locale.US ) ).atZone( ZoneId.of( "America/Montreal" ) ) .toInstant() ) 

Detalles

La Pregunta y otras Respuestas usan antiguas clases problemáticas anticuadas que ahora son heredadas, suplantadas por las clases java.time.

Usando java.time

La cadena de entrada carece de cualquier indicación de zona horaria o desplazamiento desde UTC. Entonces analizamos como un OffsetDateTime .

Especifique una Locale para determinar (a) el idioma humano para la traducción del nombre del día, nombre del mes y demás, y (b) las normas culturales que decidan los problemas de abreviación, uso de mayúsculas, puntuación, separadores, etc.

 String input = "Wed, 09 Feb 2011 12:34:27" ; Locale l = Locale.US ; DateTimeFormatter f = DateTimeFormatter.ofPattern( "EEE, dd MMM uuuu HH:mm:ss" , l ) ; LocalDateTime ldt = LocalDateTime.parse( input , f ) ; 

ldt.toString (): 2011-02-09T12: 34: 27

Zona horaria

Tanto la Pregunta como otra Respuesta ignoran la cuestión crucial de la zona horaria.

La cadena de entrada carece de zona horaria o desplazamiento. Analizamos como LocalDateTime que no es un momento en la línea de tiempo, solo una idea vaga sobre los posibles momentos. Como decir “La Navidad comienza a la medianoche del 25 de diciembre de 2017”, eso no tiene ningún significado hasta que lo ubiques en el contexto de un huso horario en particular. La Navidad llega mucho antes en Auckland Nueva Zelanda que en París, Francia, y mucho más tarde aún en Montreal Québec.

Si conoce la zona horaria prevista, asigne un ZoneId para producir un ZonedDateTime .

 ZoneId z = ZoneId.of( "America/Montreal" ) ; ZonedDateTime zdt = ldt.atZone( z ); // Assigning a time zone to determine an actual moment on the timeline. 

Mudado

Lo mejor es evitar las problemáticas antiguas clases heredadas de fecha y hora. Pero si debe interactuar con un código antiguo que aún no se ha actualizado a los tipos java.time, puede realizar conversiones entre las clases heredadas y java.time. Busque nuevos métodos para agregar a las clases antiguas .

Un java.util.Date es un momento en la línea de tiempo en UTC. Entonces, necesitamos extraer un Instant de nuestro ZonedDateTime . La clase Instant representa un momento en la línea de tiempo en UTC con una resolución de nanosegundos (hasta nueve (9) dígitos de una fracción decimal).

 Instant instant = zdt.toInstant() ; java.util.Date d = java.util.Date.from( instant ) ; // Convert from java.time to legacy class. 

Yendo en la otra dirección.

 Instant instant = d.toInstant() ; // Convert from legacy class to java.time class. ZonedDateTime zdt = instant.atZone( z ) ; // Adjust from UTC into a particular time zone. 

Acerca de java.time

El marco java.time está integrado en Java 8 y posterior. Estas clases suplantan a las problemáticas antiguas clases heredadas de fecha y hora como java.util.Date , Calendar y SimpleDateFormat .

El proyecto Joda-Time , ahora en modo de mantenimiento , aconseja la migración a las clases java.time .

Para obtener más información, consulte el Tutorial de Oracle . Y busque Stack Overflow para obtener muchos ejemplos y explicaciones. La especificación es JSR 310 .

Puede intercambiar objetos java.time directamente con su base de datos. Use un controlador JDBC que cumpla con JDBC 4.2 o posterior. Sin necesidad de cadenas, sin necesidad de clases java.sql.* .

¿Dónde obtener las clases de java.time?

  • Java SE 8 , Java SE 9 , Java SE 10 y posterior
    • Incorporado.
    • Parte de la API Java estándar con una implementación integrada.
    • Java 9 agrega algunas características y correcciones menores.
  • Java SE 6 y Java SE 7
    • Gran parte de la funcionalidad de java.time se transfiere a Java 6 y 7 en ThreeTen-Backport .
  • Androide
    • Versiones posteriores de las implementaciones del paquete de Android de las clases java.time.
    • Para Android anterior (<26), el proyecto ThreeTenABP adapta ThreeTen-Backport (mencionado anteriormente). Consulte Cómo utilizar ThreeTenABP ….

El proyecto ThreeTen-Extra amplía java.time con clases adicionales. Este proyecto es un terreno de prueba para posibles adiciones futuras a java.time. Puede encontrar algunas clases útiles aquí, como Interval , YearWeek , YearQuarter y más .