Java: fecha no analizable
Estoy intentando analizar una fecha, pero curiosamente obtengo 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 no analizable: "Miércoles, 9 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 se deba a que la configuración regional predeterminada de su computadora no es el inglés.
Deberías usar:
new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss", Locale.ENGLISH);
en cambio.
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
Tanto la pregunta como la otra respuesta utilizan clases de fecha y hora obsoletas y problemáticas que ahora son heredadas y reemplazadas por las clases java.time.
Usando java.time
La cadena de entrada carece de indicación de zona horaria o desplazamiento desde UTC. Entonces lo analizamos como un OffsetDateTime
.
Especifique a Locale
para determinar (a) el lenguaje humano para la traducción del nombre del día, el nombre del mes y demás, y (b) las normas culturales que deciden cuestiones de abreviatura, mayúsculas, puntuación, separadores y demás.
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 la otra respuesta ignoran la cuestión crucial de la zona horaria.
La cadena de entrada carece de zona horaria o desplazamiento. Lo analizamos como algo que noLocalDateTime
es un momento en la línea de tiempo, solo una idea vaga sobre posibles momentos. Como decir "La Navidad comienza a la medianoche del 25 de diciembre de 2017", eso no tiene significado hasta que lo colocas en el contexto de una zona horaria particular. La Navidad llega mucho antes en Auckland, Nueva Zelanda, que en París, Francia, y mucho más tarde aún en Montreal, Quebec.
Si conoce la zona horaria prevista, asigne un ZoneId
para producir un archivo 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 antiguas y problemáticas clases de fecha y hora heredadas. Pero si debe interactuar con código antiguo que aún no se ha actualizado a los tipos java.time, puede convertir entre las clases heredadas y java.time. Busque nuevos métodos que se agreguen a las clases antiguas .
A java.util.Date
es un momento en la línea de tiempo en UTC. Entonces necesitamos extraer un Instant
de nuestro ZonedDateTime
. La Instant
clase 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 versiones posteriores. Estas clases reemplazan a las antiguas y problemáticas clases de fecha y hora heredadas , 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. Utilice un controlador JDBC compatible con JDBC 4.2 o posterior. No hay necesidad de cadenas, no hay necesidad de java.sql.*
clases.
¿Dónde obtener las clases java.time?
- Java SE 8 , Java SE 9 , Java SE 10 y posteriores
- Incorporado.
- Parte de la API de Java estándar con una implementación incluida.
- Java 9 agrega algunas características y correcciones menores.
- Java SE 6 y Java SE 7
- Gran parte de la funcionalidad java.time está adaptada a Java 6 y 7 en ThreeTen-Backport .
- Androide
- Versiones posteriores de implementaciones de paquetes 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 campo de pruebas para posibles adiciones futuras a java.time. Puede encontrar algunas clases útiles aquí, como , Interval
, y más .YearWeek
YearQuarter