que - Java SimpleDateFormat siempre regresa enero por mes
simpledateformat tutorial (3)
TL; DR
LocalDate parsedDate = OffsetDateTime
.parse("20050912190509.0Z", DateTimeFormatter.ofPattern("uuuuMMddHHmmss.SX"))
.toLocalDate();
Esto produce una fecha LocalDate
de 2005-09-12
.
java.time
Estoy aportando la respuesta moderna. La respuesta de Suhas Phartale es correcta y fue una buena respuesta cuando se escribió hace 7 años. Ahora, la notoriamente problemática clase SimpleDateFormat
está obsoleta y tenemos mucho mejor en java.time
, la moderna API de fecha y hora de Java. Recomiendo encarecidamente que use esto en lugar de las antiguas clases de fecha y hora.
Detalles
Parece que a partir de su código usted reformatea su cadena desde AD antes de analizarla. No hay necesidad de eso, la cadena de AD se puede analizar directamente. Podríamos haberlo analizado directamente en LocalDate
, pero recomiendo analizarlo en un OffsetDateTime
para obtener el tiempo y el desplazamiento de la cadena; Como puede ver, esto se puede convertir directamente a LocalDate
después. Una LocalDate
es una fecha sin hora del día, por lo que parece coincidir con sus requisitos mejor que la clase Date
.
La cadena está en UTC (indicada por la Z
al final). Lo anterior le da la fecha de la cadena, que es la fecha en UTC. Si, en cambio, deseaba la fecha en la que se encontraba en su zona horaria local cuando era 12 de septiembre a las 19:05 en UTC:
LocalDate parsedDate = OffsetDateTime.parse(givenString, adDateTimeFormatter)
.atZoneSameInstant(ZoneId.of("America/Coral_Harbour"))
.toLocalDate();
Asumí que hemos declarado el formateador como un campo estático:
private static final DateTimeFormatter adDateTimeFormatter
= DateTimeFormatter.ofPattern("uuuuMMddHHmmss.SX");
En este caso, el resultado es el mismo, para otras zonas horarias no lo será. Por favor, sustituya su propia zona horaria deseada para America / Coral_Harbour. Para usar la configuración de zona horaria de la JVM, especifique ZoneId.systemDefault()
. Tenga en cuenta, sin embargo, que la configuración puede ser modificada por otras partes de su programa u otros programas que se ejecutan en la misma JVM, por lo que esto es frágil.
Y el punto de la respuesta de Suhas Phartale también es válido en java.time
: las cadenas de patrón de formato distinguen entre mayúsculas y minúsculas, y necesitaba usar dd
minúsculas para el día del mes.
Tutorial
Obtenga más información sobre java.time
en el tutorial de Oracle y / o busque otros recursos en la red.
Estoy trabajando para tomar un valor de fecha (createWhen) de Active Directory y traducirlo a una fecha de Java, con el fin de obtener una lista de cuentas creadas entre dos fechas. Todo funciona bien, excepto por un método: el método desde el que voy de la fecha de AD a la fecha de Java. El método se ve así:
private Date getParsedDate(String givenString) {
System.out.println("Value from AD is: " + givenString);
Date parsedDate = null;
String formattedString = this.formatDateString(givenString);
System.out.println("Formatted String is: " + formattedString);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/DD");
try {
parsedDate = sdf.parse(formattedString);
System.out.println("Final date string is: " + parsedDate.toString());
} catch (ParseException ex) {
ex.printStackTrace();
}
return parsedDate;
}
Y, para una sola pieza de datos arbitrarios de AD:
Value from AD is: 20050912190509.0Z
Formatted String is: 2005/09/12
Final date string is: Wed Jan 12 00:00:00 EST 2005
Obviamente, está recogiendo el día y el año correctamente (y si elijo incluir horas / minutos / segundos, también los incluye correctamente), pero todas las fechas se colocarán en enero por alguna razón.
Ahora, estoy seguro de que mi error es bastante simple, pero volví a revisar mi formato unas diez veces y estoy en el punto en que ya no puedo verlo. ¿Es posible que un segundo par de ojos revise mi código y señale a dónde me equivoco para que el mes sea tan incorrecto?
Gracias.
Asegúrese de no usar ''mm'' en lugar de ''MM'' o ''MMM''. Como pequeña m denota minutos y mayúsculas M denota mes.
Cambie la cadena del patrón de "aaaa / MM / DD" a "aaaa / MM / dd"
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");